Merge
This commit is contained in:
commit
66dc31f3d1
@ -110,3 +110,4 @@ cc58c11af15411042719e9c82707fdbef60a9e0f jdk7-b130
|
||||
c6f380693342feadccc5fe2c5adf500e861361aa jdk7-b133
|
||||
ddc2fcb3682ffd27f44354db666128827be7e3c3 jdk7-b134
|
||||
783bd02b4ab4596059c74b10a1793d7bd2f1c157 jdk7-b135
|
||||
2fe76e73adaa5133ac559f0b3c2c0707eca04580 jdk7-b136
|
||||
|
@ -110,3 +110,4 @@ d7532bcd3742f1576dd07ff9fbb535c9c9a276e9 jdk7-b126
|
||||
671fe2e623ffefb4b7c312be919fc71eb48c1df1 jdk7-b133
|
||||
918003855fa0dba5acf4bf1fe36526d2fc4c1ba8 jdk7-b134
|
||||
e0b72ae5dc5e824b342801c8d1d336a55eb54e2c jdk7-b135
|
||||
48ef0c712e7cbf272f47f9224db92a3c6a9e2612 jdk7-b136
|
||||
|
@ -158,3 +158,5 @@ a8d643a4db47c7b58e0bcb49c77b5c3610de86a8 hs21-b03
|
||||
3c76374706ea8a77e15aec8310e831e5734f8775 hs21-b04
|
||||
b898f0fc3cedc972d884d31a751afd75969531cf jdk7-b135
|
||||
b898f0fc3cedc972d884d31a751afd75969531cf hs21-b05
|
||||
bd586e392d93b7ed7a1636dcc8da2b6a4203a102 jdk7-b136
|
||||
bd586e392d93b7ed7a1636dcc8da2b6a4203a102 hs21-b06
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@ package sun.jvm.hotspot.jdi;
|
||||
import com.sun.jdi.*;
|
||||
import sun.jvm.hotspot.oops.Instance;
|
||||
import sun.jvm.hotspot.oops.Klass;
|
||||
import sun.jvm.hotspot.oops.OopUtilities;
|
||||
import sun.jvm.hotspot.oops.java_lang_Class;
|
||||
|
||||
public class ClassObjectReferenceImpl extends ObjectReferenceImpl
|
||||
implements ClassObjectReference {
|
||||
@ -39,7 +39,7 @@ public class ClassObjectReferenceImpl extends ObjectReferenceImpl
|
||||
|
||||
public ReferenceType reflectedType() {
|
||||
if (reflectedType == null) {
|
||||
Klass k = OopUtilities.classOopToKlass(ref());
|
||||
Klass k = java_lang_Class.asKlass(ref());
|
||||
reflectedType = vm.referenceType(k);
|
||||
}
|
||||
return reflectedType;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -64,7 +64,7 @@ public class Instance extends Oop {
|
||||
|
||||
public void iterateFields(OopVisitor visitor, boolean doVMFields) {
|
||||
super.iterateFields(visitor, doVMFields);
|
||||
((InstanceKlass) getKlass()).iterateNonStaticFields(visitor);
|
||||
((InstanceKlass) getKlass()).iterateNonStaticFields(visitor, this);
|
||||
}
|
||||
|
||||
public void printValueOn(PrintStream tty) {
|
||||
|
@ -241,6 +241,10 @@ public class InstanceKlass extends Klass {
|
||||
// Byteside of the header
|
||||
private static long headerSize;
|
||||
|
||||
public long getObjectSize(Oop object) {
|
||||
return getSizeHelper() * VM.getVM().getAddressSize();
|
||||
}
|
||||
|
||||
public static long getHeaderSize() { return headerSize; }
|
||||
|
||||
// Accessors for declared fields
|
||||
@ -459,7 +463,22 @@ public class InstanceKlass extends Klass {
|
||||
visitor.doCInt(vtableLen, true);
|
||||
visitor.doCInt(itableLen, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Visit the static fields of this InstanceKlass with the obj of
|
||||
* the visitor set to the oop holding the fields, which is
|
||||
* currently the java mirror.
|
||||
*/
|
||||
public void iterateStaticFields(OopVisitor visitor) {
|
||||
visitor.setObj(getJavaMirror());
|
||||
visitor.prologue();
|
||||
iterateStaticFieldsInternal(visitor);
|
||||
visitor.epilogue();
|
||||
|
||||
}
|
||||
|
||||
void iterateStaticFieldsInternal(OopVisitor visitor) {
|
||||
TypeArray fields = getFields();
|
||||
int length = (int) fields.getLength();
|
||||
for (int index = 0; index < length; index += NEXT_OFFSET) {
|
||||
@ -477,9 +496,9 @@ public class InstanceKlass extends Klass {
|
||||
return getSuper();
|
||||
}
|
||||
|
||||
public void iterateNonStaticFields(OopVisitor visitor) {
|
||||
public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
|
||||
if (getSuper() != null) {
|
||||
((InstanceKlass) getSuper()).iterateNonStaticFields(visitor);
|
||||
((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
|
||||
}
|
||||
TypeArray fields = getFields();
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.oops;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.memory.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
|
||||
// An InstanceKlass is the VM level representation of a Java class.
|
||||
|
||||
public class InstanceMirrorKlass extends InstanceKlass {
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||
// Just make sure it's there for now
|
||||
Type type = db.lookupType("instanceMirrorKlass");
|
||||
}
|
||||
|
||||
InstanceMirrorKlass(OopHandle handle, ObjectHeap heap) {
|
||||
super(handle, heap);
|
||||
}
|
||||
|
||||
public long getObjectSize(Oop o) {
|
||||
return java_lang_Class.getOopSize(o) * VM.getVM().getAddressSize();
|
||||
}
|
||||
|
||||
public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
|
||||
super.iterateNonStaticFields(visitor, obj);
|
||||
// Fetch the real klass from the mirror object
|
||||
Klass klass = java_lang_Class.asKlass(obj);
|
||||
if (klass instanceof InstanceKlass) {
|
||||
((InstanceKlass)klass).iterateStaticFields(visitor);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -362,7 +362,16 @@ public class ObjectHeap {
|
||||
if (klass.equals(compiledICHolderKlassHandle)) return new CompiledICHolder(handle, this);
|
||||
if (klass.equals(methodDataKlassHandle)) return new MethodData(handle, this);
|
||||
}
|
||||
if (klass.equals(instanceKlassKlassHandle)) return new InstanceKlass(handle, this);
|
||||
if (klass.equals(instanceKlassKlassHandle)) {
|
||||
InstanceKlass ik = new InstanceKlass(handle, this);
|
||||
if (ik.getName().asString().equals("java/lang/Class")) {
|
||||
// We would normally do this using the vtable style
|
||||
// lookup but since it's not used for these currently
|
||||
// it's simpler to just check for the name.
|
||||
return new InstanceMirrorKlass(handle, this);
|
||||
}
|
||||
return ik;
|
||||
}
|
||||
if (klass.equals(objArrayKlassKlassHandle)) return new ObjArrayKlass(handle, this);
|
||||
if (klass.equals(typeArrayKlassKlassHandle)) return new TypeArrayKlass(handle, this);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -103,12 +103,8 @@ public class Oop {
|
||||
// Returns the byte size of this object
|
||||
public long getObjectSize() {
|
||||
Klass k = getKlass();
|
||||
if (k instanceof InstanceKlass) {
|
||||
return ((InstanceKlass)k).getSizeHelper()
|
||||
* VM.getVM().getAddressSize();
|
||||
}
|
||||
// If it is not an instance, this method should be replaced.
|
||||
return getHeaderSize();
|
||||
// All other types should be overriding getObjectSize directly
|
||||
return ((InstanceKlass)k).getObjectSize(this);
|
||||
}
|
||||
|
||||
// Type test operations
|
||||
|
@ -74,9 +74,6 @@ public class OopUtilities implements /* imports */ JVMTIThreadState {
|
||||
private static int THREAD_STATUS_TERMINATED;
|
||||
*/
|
||||
|
||||
// java.lang.Class fields
|
||||
private static OopField hcKlassField;
|
||||
|
||||
// java.util.concurrent.locks.AbstractOwnableSynchronizer fields
|
||||
private static OopField absOwnSyncOwnerThreadField;
|
||||
|
||||
@ -268,27 +265,6 @@ public class OopUtilities implements /* imports */ JVMTIThreadState {
|
||||
return null;
|
||||
}
|
||||
|
||||
// initialize fields for java.lang.Class
|
||||
private static void initClassFields() {
|
||||
if (hcKlassField == null) {
|
||||
// hc_klass is a HotSpot magic field and hence we can't
|
||||
// find it from InstanceKlass for java.lang.Class.
|
||||
TypeDataBase db = VM.getVM().getTypeDataBase();
|
||||
int hcKlassOffset = (int) db.lookupType("java_lang_Class").getCIntegerField("klass_offset").getValue();
|
||||
if (VM.getVM().isCompressedOopsEnabled()) {
|
||||
hcKlassField = new NarrowOopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
|
||||
} else {
|
||||
hcKlassField = new OopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** get klassOop field at offset hc_klass_offset from a java.lang.Class object */
|
||||
public static Klass classOopToKlass(Oop aClass) {
|
||||
initClassFields();
|
||||
return (Klass) hcKlassField.getValue(aClass);
|
||||
}
|
||||
|
||||
// initialize fields for j.u.c.l AbstractOwnableSynchornizer class
|
||||
private static void initAbsOwnSyncFields() {
|
||||
if (absOwnSyncOwnerThreadField == null) {
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.oops;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.memory.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.types.Type;
|
||||
import sun.jvm.hotspot.types.TypeDataBase;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
import sun.jvm.hotspot.jdi.JVMTIThreadState;
|
||||
|
||||
/** A utility class encapsulating useful oop operations */
|
||||
|
||||
// initialize fields for java.lang.Class
|
||||
public class java_lang_Class {
|
||||
|
||||
// java.lang.Class fields
|
||||
static OopField klassField;
|
||||
static IntField oopSizeField;
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
// klass and oop_size are HotSpot magic fields and hence we can't
|
||||
// find them from InstanceKlass for java.lang.Class.
|
||||
Type jlc = db.lookupType("java_lang_Class");
|
||||
int klassOffset = (int) jlc.getCIntegerField("klass_offset").getValue();
|
||||
if (VM.getVM().isCompressedOopsEnabled()) {
|
||||
klassField = new NarrowOopField(new NamedFieldIdentifier("klass"), klassOffset, true);
|
||||
} else {
|
||||
klassField = new OopField(new NamedFieldIdentifier("klass"), klassOffset, true);
|
||||
}
|
||||
int oopSizeOffset = (int) jlc.getCIntegerField("oop_size_offset").getValue();
|
||||
oopSizeField = new IntField(new NamedFieldIdentifier("oop_size"), oopSizeOffset, true);
|
||||
}
|
||||
|
||||
/** get klassOop field at offset hc_klass_offset from a java.lang.Class object */
|
||||
public static Klass asKlass(Oop aClass) {
|
||||
return (Klass) java_lang_Class.klassField.getValue(aClass);
|
||||
}
|
||||
|
||||
/** get oop_size field at offset oop_size_offset from a java.lang.Class object */
|
||||
public static long getOopSize(Oop aClass) {
|
||||
return java_lang_Class.oopSizeField.getValue(aClass);
|
||||
}
|
||||
}
|
@ -839,20 +839,18 @@ public class VM {
|
||||
}
|
||||
|
||||
private void readSystemProperties() {
|
||||
final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
|
||||
systemKls.iterate(new DefaultOopVisitor() {
|
||||
ObjectReader objReader = new ObjectReader();
|
||||
public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
|
||||
if (field.getID().getName().equals("props")) {
|
||||
try {
|
||||
sysProps = (Properties) objReader.readObject(field.getValue(systemKls.getJavaMirror()));
|
||||
} catch (Exception e) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
|
||||
systemKls.iterateStaticFields(new DefaultOopVisitor() {
|
||||
ObjectReader objReader = new ObjectReader();
|
||||
public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
|
||||
if (field.getID().getName().equals("props")) {
|
||||
try {
|
||||
sysProps = (Properties) objReader.readObject(field.getValue(getObj()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -64,16 +64,16 @@ public class FinalizerInfo extends Tool {
|
||||
*/
|
||||
InstanceKlass ik =
|
||||
SystemDictionaryHelper.findInstanceKlass("java.lang.ref.Finalizer");
|
||||
final OopField queueField[] = new OopField[1];
|
||||
ik.iterateFields(new DefaultOopVisitor() {
|
||||
final Oop[] queueref = new Oop[1];
|
||||
ik.iterateStaticFields(new DefaultOopVisitor() {
|
||||
public void doOop(OopField field, boolean isVMField) {
|
||||
String name = field.getID().getName();
|
||||
if (name.equals("queue")) {
|
||||
queueField[0] = field;
|
||||
}
|
||||
String name = field.getID().getName();
|
||||
if (name.equals("queue")) {
|
||||
queueref[0] = field.getValue(getObj());
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
Oop queue = queueField[0].getValue(ik);
|
||||
});
|
||||
Oop queue = queueref[0];
|
||||
|
||||
InstanceKlass k = (InstanceKlass) queue.getKlass();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -164,7 +164,7 @@ public class HeapGXLWriter extends AbstractHeapGraphWriter {
|
||||
|
||||
protected void writeClass(Instance instance) throws IOException {
|
||||
writeObjectHeader(instance);
|
||||
Klass reflectedType = OopUtilities.classOopToKlass(instance);
|
||||
Klass reflectedType = java_lang_Class.asKlass(instance);
|
||||
boolean isInstanceKlass = (reflectedType instanceof InstanceKlass);
|
||||
// reflectedType is null for primitive types (int.class etc).
|
||||
if (reflectedType != null) {
|
||||
|
@ -455,7 +455,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
}
|
||||
|
||||
protected void writeClass(Instance instance) throws IOException {
|
||||
Klass reflectedKlass = OopUtilities.classOopToKlass(instance);
|
||||
Klass reflectedKlass = java_lang_Class.asKlass(instance);
|
||||
// dump instance record only for primitive type Class objects.
|
||||
// all other Class objects are covered by writeClassDumpRecords.
|
||||
if (reflectedKlass == null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -117,10 +117,10 @@ public class ReversePtrsAnalysis {
|
||||
public boolean doObj(Oop obj) {
|
||||
if (obj instanceof InstanceKlass) {
|
||||
final InstanceKlass ik = (InstanceKlass) obj;
|
||||
ik.iterateFields(
|
||||
ik.iterateStaticFields(
|
||||
new DefaultOopVisitor() {
|
||||
public void doOop(OopField field, boolean isVMField) {
|
||||
Oop next = field.getValue(ik);
|
||||
Oop next = field.getValue(getObj());
|
||||
LivenessPathElement lp = new LivenessPathElement(null,
|
||||
new NamedFieldIdentifier("Static field \"" +
|
||||
field.getID().getName() +
|
||||
@ -142,8 +142,7 @@ public class ReversePtrsAnalysis {
|
||||
System.err.println();
|
||||
}
|
||||
}
|
||||
},
|
||||
false);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -158,7 +158,7 @@ public class JSJavaFactoryImpl implements JSJavaFactory {
|
||||
} else if (className.equals(javaLangThread())) {
|
||||
res = new JSJavaThread(instance, this);
|
||||
} else if (className.equals(javaLangClass())) {
|
||||
Klass reflectedType = OopUtilities.classOopToKlass(instance);
|
||||
Klass reflectedType = java_lang_Class.asKlass(instance);
|
||||
if (reflectedType != null) {
|
||||
JSJavaKlass jk = newJSJavaKlass(reflectedType);
|
||||
// we don't support mirrors of VM internal Klasses
|
||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
|
||||
|
||||
HS_MAJOR_VER=21
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=06
|
||||
HS_BUILD_NUMBER=07
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=7
|
||||
|
@ -102,7 +102,7 @@ all: $(EXEC)
|
||||
|
||||
$(EXEC) : $(OBJECTS)
|
||||
@echo Making adlc
|
||||
$(QUIETLY) $(LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS)
|
||||
$(QUIETLY) $(HOST.LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS)
|
||||
|
||||
# Random dependencies:
|
||||
$(OBJECTS): opcodes.hpp classes.hpp adlc.hpp adlcVMDeps.hpp adlparse.hpp archDesc.hpp arena.hpp dict2.hpp filebuff.hpp forms.hpp formsopt.hpp formssel.hpp
|
||||
@ -204,14 +204,14 @@ PROCESS_AD_FILES = awk '{ \
|
||||
$(OUTDIR)/%.o: %.cpp
|
||||
@echo Compiling $<
|
||||
$(QUIETLY) $(REMOVE_TARGET)
|
||||
$(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
|
||||
$(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE)
|
||||
|
||||
# Some object files are given a prefix, to disambiguate
|
||||
# them from objects of the same name built for the VM.
|
||||
$(OUTDIR)/adlc-%.o: %.cpp
|
||||
@echo Compiling $<
|
||||
$(QUIETLY) $(REMOVE_TARGET)
|
||||
$(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
|
||||
$(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE)
|
||||
|
||||
# #########################################################################
|
||||
|
||||
|
@ -30,9 +30,13 @@
|
||||
ifdef CROSS_COMPILE_ARCH
|
||||
CPP = $(ALT_COMPILER_PATH)/g++
|
||||
CC = $(ALT_COMPILER_PATH)/gcc
|
||||
HOSTCPP = g++
|
||||
HOSTCC = gcc
|
||||
else
|
||||
CPP = g++
|
||||
CC = gcc
|
||||
HOSTCPP = $(CPP)
|
||||
HOSTCC = $(CC)
|
||||
endif
|
||||
|
||||
AS = $(CC) -c
|
||||
|
@ -55,6 +55,14 @@ LINK_NOPROF.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS)
|
||||
LINK_LIB.CC = $(CCC) $(LFLAGS) $(SHARED_FLAG)
|
||||
PREPROCESS.CC = $(CC_COMPILE) -E
|
||||
|
||||
# cross compiling the jvm with c2 requires host compilers to build
|
||||
# adlc tool
|
||||
|
||||
HOST.CC_COMPILE = $(HOSTCPP) $(CPPFLAGS) $(CFLAGS)
|
||||
HOST.COMPILE.CC = $(HOST.CC_COMPILE) -c
|
||||
HOST.LINK_NOPROF.CC = $(HOSTCPP) $(LFLAGS) $(AOUT_FLAGS)
|
||||
|
||||
|
||||
# Effect of REMOVE_TARGET is to delete out-of-date files during "gnumake -k".
|
||||
REMOVE_TARGET = rm -f $@
|
||||
|
||||
|
@ -29,6 +29,9 @@ CPP = CC
|
||||
CC = cc
|
||||
AS = $(CC) -c
|
||||
|
||||
HOSTCPP = $(CPP)
|
||||
HOSTCC = $(CC)
|
||||
|
||||
ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
|
||||
ARCHFLAG/i486 = -m32
|
||||
ARCHFLAG/amd64 = -m64
|
||||
|
@ -93,16 +93,15 @@ if "%MSC_VER%" == "1500" (
|
||||
echo Will generate VC9 {Visual Studio 2008}
|
||||
) else (
|
||||
if "%MSC_VER%" == "1600" (
|
||||
echo Detected Visual Studio 2010, but
|
||||
echo will generate VC9 {Visual Studio 2008}
|
||||
echo Use conversion wizard in VS 2010.
|
||||
echo Will generate VC10 {Visual Studio 2010}
|
||||
set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj
|
||||
) else (
|
||||
echo Will generate VC7 project {Visual Studio 2003 .NET}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
echo %ProjectFile%
|
||||
echo %ProjectFile%
|
||||
echo **************************************************************
|
||||
|
||||
REM Test all variables to see whether the directories they
|
||||
|
@ -27,10 +27,6 @@
|
||||
# This is used externally by both batch and IDE builds, so can't
|
||||
# reference any of the HOTSPOTWORKSPACE, HOTSPOTBUILDSPACE,
|
||||
# HOTSPOTRELEASEBINDEST, or HOTSPOTDEBUGBINDEST environment variables.
|
||||
#
|
||||
# NOTE: unfortunately the ProjectCreatorSources list must be kept
|
||||
# synchronized between this and the Solaris version
|
||||
# (make/solaris/makefiles/projectcreator.make).
|
||||
|
||||
ProjectCreatorSources=\
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\DirectoryTree.java \
|
||||
@ -42,6 +38,7 @@ ProjectCreatorSources=\
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC7.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC8.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC9.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC10.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\Util.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\BuildConfig.java \
|
||||
$(WorkSpace)\src\share\tools\ProjectCreator\ArgsParser.java
|
||||
|
@ -65,8 +65,8 @@ VcVersion=VC9
|
||||
|
||||
!elseif "$(MSC_VER)" == "1600"
|
||||
|
||||
# for compatibility - we don't yet have a ProjectCreator for VC10
|
||||
VcVersion=VC9
|
||||
VcVersion=VC10
|
||||
ProjectFile=jvm.vcxproj
|
||||
|
||||
!else
|
||||
|
||||
|
@ -1188,8 +1188,8 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
__ st_ptr(O2, XXX_STATE(_stack)); // PREPUSH
|
||||
|
||||
__ lduh(max_stack, O3); // Full size expression stack
|
||||
guarantee(!EnableMethodHandles, "no support yet for java.lang.invoke.MethodHandle"); //6815692
|
||||
//6815692//if (EnableMethodHandles)
|
||||
guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
|
||||
//6815692//if (EnableInvokeDynamic)
|
||||
//6815692// __ inc(O3, methodOopDesc::extra_stack_entries());
|
||||
__ sll(O3, LogBytesPerWord, O3);
|
||||
__ sub(O2, O3, O3);
|
||||
|
@ -743,12 +743,12 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register cache, Register
|
||||
if (index_size == sizeof(u2)) {
|
||||
get_2_byte_integer_at_bcp(bcp_offset, cache, tmp, Unsigned);
|
||||
} else if (index_size == sizeof(u4)) {
|
||||
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
||||
assert(EnableInvokeDynamic, "giant index used only for JSR 292");
|
||||
get_4_byte_integer_at_bcp(bcp_offset, cache, tmp);
|
||||
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
||||
xor3(tmp, -1, tmp); // convert to plain index
|
||||
} else if (index_size == sizeof(u1)) {
|
||||
assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
|
||||
assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
|
||||
ldub(Lbcp, bcp_offset, tmp);
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
|
@ -262,7 +262,7 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
// Method handle invoker
|
||||
// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
|
||||
address InterpreterGenerator::generate_method_handle_entry(void) {
|
||||
if (!EnableMethodHandles) {
|
||||
if (!EnableInvokeDynamic) {
|
||||
return generate_abstract_entry();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1769,6 +1769,7 @@ static void create_inner_frame(MacroAssembler* masm, bool* already_created) {
|
||||
// returns.
|
||||
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
methodHandle method,
|
||||
int compile_id,
|
||||
int total_in_args,
|
||||
int comp_args_on_stack, // in VMRegStackSlots
|
||||
BasicType *in_sig_bt,
|
||||
@ -2462,6 +2463,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
__ flush();
|
||||
|
||||
nmethod *nm = nmethod::new_native_nmethod(method,
|
||||
compile_id,
|
||||
masm->code(),
|
||||
vep_offset,
|
||||
frame_complete,
|
||||
|
@ -1843,6 +1843,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong;
|
||||
// registers? True for Intel but false for most RISCs
|
||||
const bool Matcher::clone_shift_expressions = false;
|
||||
|
||||
// Do we need to mask the count passed to shift instructions or does
|
||||
// the cpu only look at the lower 5/6 bits anyway?
|
||||
const bool Matcher::need_masked_shift_count = false;
|
||||
|
||||
bool Matcher::narrow_oop_use_complex_address() {
|
||||
NOT_LP64(ShouldNotCallThis());
|
||||
assert(UseCompressedOops, "only for compressed oops code");
|
||||
|
@ -334,8 +334,8 @@ void TemplateTable::ldc(bool wide) {
|
||||
void TemplateTable::fast_aldc(bool wide) {
|
||||
transition(vtos, atos);
|
||||
|
||||
if (!EnableMethodHandles) {
|
||||
// We should not encounter this bytecode if !EnableMethodHandles.
|
||||
if (!EnableInvokeDynamic) {
|
||||
// We should not encounter this bytecode if !EnableInvokeDynamic.
|
||||
// The verifier will stop it. However, if we get past the verifier,
|
||||
// this will stop the thread in a reasonable way, without crashing the JVM.
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
|
||||
|
@ -3510,7 +3510,6 @@ bool Assembler::reachable(AddressLiteral adr) {
|
||||
// anywhere in the codeCache then we are always reachable.
|
||||
// This would have to change if we ever save/restore shared code
|
||||
// to be more pessimistic.
|
||||
|
||||
disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int));
|
||||
if (!is_simm32(disp)) return false;
|
||||
disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int));
|
||||
@ -3534,6 +3533,14 @@ bool Assembler::reachable(AddressLiteral adr) {
|
||||
return is_simm32(disp);
|
||||
}
|
||||
|
||||
// Check if the polling page is not reachable from the code cache using rip-relative
|
||||
// addressing.
|
||||
bool Assembler::is_polling_page_far() {
|
||||
intptr_t addr = (intptr_t)os::get_polling_page();
|
||||
return !is_simm32(addr - (intptr_t)CodeCache::low_bound()) ||
|
||||
!is_simm32(addr - (intptr_t)CodeCache::high_bound());
|
||||
}
|
||||
|
||||
void Assembler::emit_data64(jlong data,
|
||||
relocInfo::relocType rtype,
|
||||
int format) {
|
||||
@ -6886,6 +6893,11 @@ void MacroAssembler::sign_extend_short(Register reg) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::testl(Register dst, AddressLiteral src) {
|
||||
assert(reachable(src), "Address should be reachable");
|
||||
testl(dst, as_Address(src));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef SERIALGC
|
||||
|
||||
@ -7121,17 +7133,6 @@ void MacroAssembler::subptr(Register dst, Register src) {
|
||||
LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src));
|
||||
}
|
||||
|
||||
void MacroAssembler::test32(Register src1, AddressLiteral src2) {
|
||||
// src2 must be rval
|
||||
|
||||
if (reachable(src2)) {
|
||||
testl(src1, as_Address(src2));
|
||||
} else {
|
||||
lea(rscratch1, src2);
|
||||
testl(src1, Address(rscratch1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// C++ bool manipulation
|
||||
void MacroAssembler::testbool(Register dst) {
|
||||
if(sizeof(bool) == 1)
|
||||
@ -7768,6 +7769,28 @@ void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov32(Condition cc, Register dst, Address src) {
|
||||
if (VM_Version::supports_cmov()) {
|
||||
cmovl(cc, dst, src);
|
||||
} else {
|
||||
Label L;
|
||||
jccb(negate_condition(cc), L);
|
||||
movl(dst, src);
|
||||
bind(L);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
|
||||
if (VM_Version::supports_cmov()) {
|
||||
cmovl(cc, dst, src);
|
||||
} else {
|
||||
Label L;
|
||||
jccb(negate_condition(cc), L);
|
||||
movl(dst, src);
|
||||
bind(L);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::verify_oop(Register reg, const char* s) {
|
||||
if (!VerifyOops) return;
|
||||
|
||||
@ -9018,14 +9041,7 @@ void MacroAssembler::string_compare(Register str1, Register str2,
|
||||
movl(result, cnt1);
|
||||
subl(cnt1, cnt2);
|
||||
push(cnt1);
|
||||
if (VM_Version::supports_cmov()) {
|
||||
cmovl(Assembler::lessEqual, cnt2, result);
|
||||
} else {
|
||||
Label GT_LABEL;
|
||||
jccb(Assembler::greater, GT_LABEL);
|
||||
movl(cnt2, result);
|
||||
bind(GT_LABEL);
|
||||
}
|
||||
cmov32(Assembler::lessEqual, cnt2, result);
|
||||
|
||||
// Is the minimum length zero?
|
||||
testl(cnt2, cnt2);
|
||||
|
@ -580,7 +580,6 @@ private:
|
||||
void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
|
||||
void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0);
|
||||
|
||||
|
||||
bool reachable(AddressLiteral adr) NOT_LP64({ return true;});
|
||||
|
||||
// These are all easily abused and hence protected
|
||||
@ -683,6 +682,8 @@ private:
|
||||
static bool is_simm32(int32_t x) { return true; }
|
||||
#endif // _LP64
|
||||
|
||||
static bool is_polling_page_far() NOT_LP64({ return false;});
|
||||
|
||||
// Generic instructions
|
||||
// Does 32bit or 64bit as needed for the platform. In some sense these
|
||||
// belong in macro assembler but there is no need for both varieties to exist
|
||||
@ -2094,7 +2095,10 @@ class MacroAssembler: public Assembler {
|
||||
|
||||
void leal32(Register dst, Address src) { leal(dst, src); }
|
||||
|
||||
void test32(Register src1, AddressLiteral src2);
|
||||
// Import other testl() methods from the parent class or else
|
||||
// they will be hidden by the following overriding declaration.
|
||||
using Assembler::testl;
|
||||
void testl(Register dst, AddressLiteral src);
|
||||
|
||||
void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
|
||||
void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
|
||||
@ -2240,10 +2244,13 @@ public:
|
||||
|
||||
// Data
|
||||
|
||||
void cmov(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
|
||||
void cmov32( Condition cc, Register dst, Address src);
|
||||
void cmov32( Condition cc, Register dst, Register src);
|
||||
|
||||
void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
|
||||
void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
|
||||
void cmov( Condition cc, Register dst, Register src) { cmovptr(cc, dst, src); }
|
||||
|
||||
void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmov32(cc, dst, src)); }
|
||||
void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmov32(cc, dst, src)); }
|
||||
|
||||
void movoop(Register dst, jobject obj);
|
||||
void movoop(Address dst, jobject obj);
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/assembler.hpp"
|
||||
#include "c1/c1_Compilation.hpp"
|
||||
#include "c1/c1_LIRAssembler.hpp"
|
||||
#include "c1/c1_MacroAssembler.hpp"
|
||||
@ -569,24 +570,13 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst,
|
||||
__ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
|
||||
|
||||
// compute minimum length (in rax) and difference of lengths (on top of stack)
|
||||
if (VM_Version::supports_cmov()) {
|
||||
__ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
|
||||
__ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
|
||||
__ mov (rcx, rbx);
|
||||
__ subptr (rbx, rax); // subtract lengths
|
||||
__ push (rbx); // result
|
||||
__ cmov (Assembler::lessEqual, rax, rcx);
|
||||
} else {
|
||||
Label L;
|
||||
__ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
|
||||
__ movl (rcx, Address(rax, java_lang_String::count_offset_in_bytes()));
|
||||
__ mov (rax, rbx);
|
||||
__ subptr (rbx, rcx);
|
||||
__ push (rbx);
|
||||
__ jcc (Assembler::lessEqual, L);
|
||||
__ mov (rax, rcx);
|
||||
__ bind (L);
|
||||
}
|
||||
__ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
|
||||
__ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
|
||||
__ mov (rcx, rbx);
|
||||
__ subptr(rbx, rax); // subtract lengths
|
||||
__ push (rbx); // result
|
||||
__ cmov (Assembler::lessEqual, rax, rcx);
|
||||
|
||||
// is minimum length 0?
|
||||
Label noLoop, haveResult;
|
||||
__ testptr (rax, rax);
|
||||
@ -648,12 +638,13 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||
AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()),
|
||||
relocInfo::poll_return_type);
|
||||
|
||||
// NOTE: the requires that the polling page be reachable else the reloc
|
||||
// goes to the movq that loads the address and not the faulting instruction
|
||||
// which breaks the signal handler code
|
||||
|
||||
__ test32(rax, polling_page);
|
||||
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
__ lea(rscratch1, polling_page);
|
||||
__ relocate(relocInfo::poll_return_type);
|
||||
__ testl(rax, Address(rscratch1, 0));
|
||||
} else {
|
||||
__ testl(rax, polling_page);
|
||||
}
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
@ -661,20 +652,17 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
||||
AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()),
|
||||
relocInfo::poll_type);
|
||||
|
||||
if (info != NULL) {
|
||||
add_debug_info_for_branch(info);
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
guarantee(info != NULL, "Shouldn't be NULL");
|
||||
int offset = __ offset();
|
||||
|
||||
// NOTE: the requires that the polling page be reachable else the reloc
|
||||
// goes to the movq that loads the address and not the faulting instruction
|
||||
// which breaks the signal handler code
|
||||
|
||||
__ test32(rax, polling_page);
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
__ lea(rscratch1, polling_page);
|
||||
offset = __ offset();
|
||||
add_debug_info_for_branch(info);
|
||||
__ testl(rax, Address(rscratch1, 0));
|
||||
} else {
|
||||
add_debug_info_for_branch(info);
|
||||
__ testl(rax, polling_page);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/assembler.hpp"
|
||||
#include "c1/c1_Defs.hpp"
|
||||
#include "c1/c1_MacroAssembler.hpp"
|
||||
#include "c1/c1_Runtime1.hpp"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -125,7 +125,7 @@
|
||||
// Entry frames
|
||||
#ifdef AMD64
|
||||
#ifdef _WIN64
|
||||
entry_frame_after_call_words = 8,
|
||||
entry_frame_after_call_words = 28,
|
||||
entry_frame_call_wrapper_offset = 2,
|
||||
|
||||
arg_reg_save_area_bytes = 32, // Register argument save area
|
||||
|
@ -215,7 +215,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_off
|
||||
if (index_size == sizeof(u2)) {
|
||||
load_unsigned_short(reg, Address(rsi, bcp_offset));
|
||||
} else if (index_size == sizeof(u4)) {
|
||||
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
||||
assert(EnableInvokeDynamic, "giant index used only for JSR 292");
|
||||
movl(reg, Address(rsi, bcp_offset));
|
||||
// Check if the secondary index definition is still ~x, otherwise
|
||||
// we have to change the following assembler code to calculate the
|
||||
@ -223,7 +223,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_off
|
||||
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
||||
notl(reg); // convert to plain index
|
||||
} else if (index_size == sizeof(u1)) {
|
||||
assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
|
||||
assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
|
||||
load_unsigned_byte(reg, Address(rsi, bcp_offset));
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
|
@ -213,7 +213,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
|
||||
if (index_size == sizeof(u2)) {
|
||||
load_unsigned_short(index, Address(r13, bcp_offset));
|
||||
} else if (index_size == sizeof(u4)) {
|
||||
assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
|
||||
assert(EnableInvokeDynamic, "giant index used only for JSR 292");
|
||||
movl(index, Address(r13, bcp_offset));
|
||||
// Check if the secondary index definition is still ~x, otherwise
|
||||
// we have to change the following assembler code to calculate the
|
||||
@ -221,7 +221,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
|
||||
assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
|
||||
notl(index); // convert to plain index
|
||||
} else if (index_size == sizeof(u1)) {
|
||||
assert(EnableMethodHandles, "tiny index used only for EnableMethodHandles");
|
||||
assert(EnableInvokeDynamic, "tiny index used only for JSR 292");
|
||||
load_unsigned_byte(index, Address(r13, bcp_offset));
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
|
@ -233,7 +233,7 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
// Method handle invoker
|
||||
// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
|
||||
address InterpreterGenerator::generate_method_handle_entry(void) {
|
||||
if (!EnableMethodHandles) {
|
||||
if (!EnableInvokeDynamic) {
|
||||
return generate_abstract_entry();
|
||||
}
|
||||
|
||||
|
@ -320,7 +320,7 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
// Method handle invoker
|
||||
// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
|
||||
address InterpreterGenerator::generate_method_handle_entry(void) {
|
||||
if (!EnableMethodHandles) {
|
||||
if (!EnableInvokeDynamic) {
|
||||
return generate_abstract_entry();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -519,7 +519,11 @@ class NativeReturnX: public NativeInstruction {
|
||||
class NativeTstRegMem: public NativeInstruction {
|
||||
public:
|
||||
enum Intel_specific_constants {
|
||||
instruction_code_memXregl = 0x85
|
||||
instruction_rex_prefix_mask = 0xF0,
|
||||
instruction_rex_prefix = Assembler::REX,
|
||||
instruction_code_memXregl = 0x85,
|
||||
modrm_mask = 0x38, // select reg from the ModRM byte
|
||||
modrm_reg = 0x00 // rax
|
||||
};
|
||||
};
|
||||
|
||||
@ -533,12 +537,25 @@ inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) =
|
||||
(ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
|
||||
inline bool NativeInstruction::is_safepoint_poll() {
|
||||
#ifdef AMD64
|
||||
if ( ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
|
||||
ubyte_at(1) == 0x05 ) { // 00 rax 101
|
||||
address fault = addr_at(6) + int_at(2);
|
||||
return os::is_poll_address(fault);
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
// two cases, depending on the choice of the base register in the address.
|
||||
if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
|
||||
ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
|
||||
(ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
|
||||
ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
|
||||
(ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
|
||||
ubyte_at(1) == 0x05) { // 00 rax 101
|
||||
address fault = addr_at(6) + int_at(2);
|
||||
return os::is_poll_address(fault);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -198,41 +198,44 @@ void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen)
|
||||
|
||||
void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
|
||||
#ifdef _LP64
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
WhichOperand which = (WhichOperand) format();
|
||||
// This format is imm but it is really disp32
|
||||
which = Assembler::disp32_operand;
|
||||
address orig_addr = old_addr_for(addr(), src, dest);
|
||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
||||
if (!Assembler::is_polling_page_far()) {
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
WhichOperand which = (WhichOperand) format();
|
||||
// This format is imm but it is really disp32
|
||||
which = Assembler::disp32_operand;
|
||||
address orig_addr = old_addr_for(addr(), src, dest);
|
||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
||||
|
||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
||||
|
||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
||||
* disp = (int32_t)new_disp;
|
||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
||||
|
||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
||||
* disp = (int32_t)new_disp;
|
||||
}
|
||||
#endif // _LP64
|
||||
}
|
||||
|
||||
void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
|
||||
#ifdef _LP64
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
WhichOperand which = (WhichOperand) format();
|
||||
// This format is imm but it is really disp32
|
||||
which = Assembler::disp32_operand;
|
||||
address orig_addr = old_addr_for(addr(), src, dest);
|
||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
||||
if (!Assembler::is_polling_page_far()) {
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
WhichOperand which = (WhichOperand) format();
|
||||
// This format is imm but it is really disp32
|
||||
which = Assembler::disp32_operand;
|
||||
address orig_addr = old_addr_for(addr(), src, dest);
|
||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
||||
|
||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
||||
|
||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
||||
* disp = (int32_t)new_disp;
|
||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
||||
* disp = (int32_t)new_disp;
|
||||
}
|
||||
#endif // _LP64
|
||||
}
|
||||
|
@ -1111,6 +1111,7 @@ void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_ty
|
||||
// returns.
|
||||
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
methodHandle method,
|
||||
int compile_id,
|
||||
int total_in_args,
|
||||
int comp_args_on_stack,
|
||||
BasicType *in_sig_bt,
|
||||
@ -1854,6 +1855,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
__ flush();
|
||||
|
||||
nmethod *nm = nmethod::new_native_nmethod(method,
|
||||
compile_id,
|
||||
masm->code(),
|
||||
vep_offset,
|
||||
frame_complete,
|
||||
|
@ -1174,6 +1174,7 @@ static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMR
|
||||
// returns.
|
||||
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
methodHandle method,
|
||||
int compile_id,
|
||||
int total_in_args,
|
||||
int comp_args_on_stack,
|
||||
BasicType *in_sig_bt,
|
||||
@ -1881,6 +1882,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
__ flush();
|
||||
|
||||
nmethod *nm = nmethod::new_native_nmethod(method,
|
||||
compile_id,
|
||||
masm->code(),
|
||||
vep_offset,
|
||||
frame_complete,
|
||||
|
@ -144,8 +144,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// [ return_from_Java ] <--- rsp
|
||||
// [ argument word n ]
|
||||
// ...
|
||||
// -8 [ argument word 1 ]
|
||||
// -7 [ saved r15 ] <--- rsp_after_call
|
||||
// -28 [ argument word 1 ]
|
||||
// -27 [ saved xmm15 ] <--- rsp_after_call
|
||||
// [ saved xmm7-xmm14 ]
|
||||
// -9 [ saved xmm6 ] (each xmm register takes 2 slots)
|
||||
// -7 [ saved r15 ]
|
||||
// -6 [ saved r14 ]
|
||||
// -5 [ saved r13 ]
|
||||
// -4 [ saved r12 ]
|
||||
@ -169,8 +172,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// Call stub stack layout word offsets from rbp
|
||||
enum call_stub_layout {
|
||||
#ifdef _WIN64
|
||||
rsp_after_call_off = -7,
|
||||
r15_off = rsp_after_call_off,
|
||||
xmm_save_first = 6, // save from xmm6
|
||||
xmm_save_last = 15, // to xmm15
|
||||
xmm_save_base = -9,
|
||||
rsp_after_call_off = xmm_save_base - 2 * (xmm_save_last - xmm_save_first), // -27
|
||||
r15_off = -7,
|
||||
r14_off = -6,
|
||||
r13_off = -5,
|
||||
r12_off = -4,
|
||||
@ -208,6 +214,13 @@ class StubGenerator: public StubCodeGenerator {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef _WIN64
|
||||
Address xmm_save(int reg) {
|
||||
assert(reg >= xmm_save_first && reg <= xmm_save_last, "XMM register number out of range");
|
||||
return Address(rbp, (xmm_save_base - (reg - xmm_save_first) * 2) * wordSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
address generate_call_stub(address& return_address) {
|
||||
assert((int)frame::entry_frame_after_call_words == -(int)rsp_after_call_off + 1 &&
|
||||
(int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off,
|
||||
@ -256,8 +269,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ movptr(r13_save, r13);
|
||||
__ movptr(r14_save, r14);
|
||||
__ movptr(r15_save, r15);
|
||||
|
||||
#ifdef _WIN64
|
||||
for (int i = 6; i <= 15; i++) {
|
||||
__ movdqu(xmm_save(i), as_XMMRegister(i));
|
||||
}
|
||||
|
||||
const Address rdi_save(rbp, rdi_off * wordSize);
|
||||
const Address rsi_save(rbp, rsi_off * wordSize);
|
||||
|
||||
@ -360,6 +376,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
#endif
|
||||
|
||||
// restore regs belonging to calling function
|
||||
#ifdef _WIN64
|
||||
for (int i = 15; i >= 6; i--) {
|
||||
__ movdqu(as_XMMRegister(i), xmm_save(i));
|
||||
}
|
||||
#endif
|
||||
__ movptr(r15, r15_save);
|
||||
__ movptr(r14, r14_save);
|
||||
__ movptr(r13, r13_save);
|
||||
@ -2428,8 +2449,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
//
|
||||
address generate_generic_copy(const char *name,
|
||||
address byte_copy_entry, address short_copy_entry,
|
||||
address int_copy_entry, address long_copy_entry,
|
||||
address oop_copy_entry, address checkcast_copy_entry) {
|
||||
address int_copy_entry, address oop_copy_entry,
|
||||
address long_copy_entry, address checkcast_copy_entry) {
|
||||
|
||||
Label L_failed, L_failed_0, L_objArray;
|
||||
Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs;
|
||||
|
@ -1527,7 +1527,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
|
||||
if (interpreter_frame != NULL) {
|
||||
#ifdef ASSERT
|
||||
if (!EnableMethodHandles)
|
||||
if (!EnableInvokeDynamic)
|
||||
// @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
|
||||
// Probably, since deoptimization doesn't work yet.
|
||||
assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
|
||||
|
@ -1541,7 +1541,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
tempcount* Interpreter::stackElementWords + popframe_extra_args;
|
||||
if (interpreter_frame != NULL) {
|
||||
#ifdef ASSERT
|
||||
if (!EnableMethodHandles)
|
||||
if (!EnableInvokeDynamic)
|
||||
// @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
|
||||
// Probably, since deoptimization doesn't work yet.
|
||||
assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/assembler.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "interpreter/templateTable.hpp"
|
||||
@ -391,8 +392,8 @@ void TemplateTable::ldc(bool wide) {
|
||||
void TemplateTable::fast_aldc(bool wide) {
|
||||
transition(vtos, atos);
|
||||
|
||||
if (!EnableMethodHandles) {
|
||||
// We should not encounter this bytecode if !EnableMethodHandles.
|
||||
if (!EnableInvokeDynamic) {
|
||||
// We should not encounter this bytecode if !EnableInvokeDynamic.
|
||||
// The verifier will stop it. However, if we get past the verifier,
|
||||
// this will stop the thread in a reasonable way, without crashing the JVM.
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
|
||||
@ -1939,18 +1940,10 @@ void TemplateTable::fast_binaryswitch() {
|
||||
__ movl(temp, Address(array, h, Address::times_8, 0*wordSize));
|
||||
__ bswapl(temp);
|
||||
__ cmpl(key, temp);
|
||||
if (VM_Version::supports_cmov()) {
|
||||
__ cmovl(Assembler::less , j, h); // j = h if (key < array[h].fast_match())
|
||||
__ cmovl(Assembler::greaterEqual, i, h); // i = h if (key >= array[h].fast_match())
|
||||
} else {
|
||||
Label set_i, end_of_if;
|
||||
__ jccb(Assembler::greaterEqual, set_i); // {
|
||||
__ mov(j, h); // j = h;
|
||||
__ jmp(end_of_if); // }
|
||||
__ bind(set_i); // else {
|
||||
__ mov(i, h); // i = h;
|
||||
__ bind(end_of_if); // }
|
||||
}
|
||||
// j = h if (key < array[h].fast_match())
|
||||
__ cmov32(Assembler::less , j, h);
|
||||
// i = h if (key >= array[h].fast_match())
|
||||
__ cmov32(Assembler::greaterEqual, i, h);
|
||||
// while (i+1 < j)
|
||||
__ bind(entry);
|
||||
__ leal(h, Address(i, 1)); // i+1
|
||||
@ -3478,22 +3471,14 @@ void TemplateTable::monitorenter() {
|
||||
|
||||
// find a free slot in the monitor block (result in rdx)
|
||||
{ Label entry, loop, exit;
|
||||
__ movptr(rcx, monitor_block_top); // points to current entry, starting with top-most entry
|
||||
__ lea(rbx, monitor_block_bot); // points to word before bottom of monitor block
|
||||
__ movptr(rcx, monitor_block_top); // points to current entry, starting with top-most entry
|
||||
|
||||
__ lea(rbx, monitor_block_bot); // points to word before bottom of monitor block
|
||||
__ jmpb(entry);
|
||||
|
||||
__ bind(loop);
|
||||
__ cmpptr(Address(rcx, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); // check if current entry is used
|
||||
|
||||
// TODO - need new func here - kbt
|
||||
if (VM_Version::supports_cmov()) {
|
||||
__ cmov(Assembler::equal, rdx, rcx); // if not used then remember entry in rdx
|
||||
} else {
|
||||
Label L;
|
||||
__ jccb(Assembler::notEqual, L);
|
||||
__ mov(rdx, rcx); // if not used then remember entry in rdx
|
||||
__ bind(L);
|
||||
}
|
||||
__ cmovptr(Assembler::equal, rdx, rcx); // if not used then remember entry in rdx
|
||||
__ cmpptr(rax, Address(rcx, BasicObjectLock::obj_offset_in_bytes())); // check if current entry is for same object
|
||||
__ jccb(Assembler::equal, exit); // if same object then stop searching
|
||||
__ addptr(rcx, entry_size); // otherwise advance to next entry
|
||||
|
@ -405,8 +405,8 @@ void TemplateTable::ldc(bool wide) {
|
||||
void TemplateTable::fast_aldc(bool wide) {
|
||||
transition(vtos, atos);
|
||||
|
||||
if (!EnableMethodHandles) {
|
||||
// We should not encounter this bytecode if !EnableMethodHandles.
|
||||
if (!EnableInvokeDynamic) {
|
||||
// We should not encounter this bytecode if !EnableInvokeDynamic.
|
||||
// The verifier will stop it. However, if we get past the verifier,
|
||||
// this will stop the thread in a reasonable way, without crashing the JVM.
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
|
||||
|
@ -429,6 +429,11 @@ void VM_Version::get_processor_features() {
|
||||
UseXmmI2D = false;
|
||||
}
|
||||
}
|
||||
if( FLAG_IS_DEFAULT(UseSSE42Intrinsics) ) {
|
||||
if( supports_sse4_2() && UseSSE >= 4 ) {
|
||||
UseSSE42Intrinsics = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Use count leading zeros count instruction if available.
|
||||
if (supports_lzcnt()) {
|
||||
|
@ -1393,6 +1393,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong;
|
||||
// registers? True for Intel but false for most RISCs
|
||||
const bool Matcher::clone_shift_expressions = true;
|
||||
|
||||
// Do we need to mask the count passed to shift instructions or does
|
||||
// the cpu only look at the lower 5/6 bits anyway?
|
||||
const bool Matcher::need_masked_shift_count = false;
|
||||
|
||||
bool Matcher::narrow_oop_use_complex_address() {
|
||||
ShouldNotCallThis();
|
||||
return true;
|
||||
|
@ -574,12 +574,11 @@ int MachCallDynamicJavaNode::ret_addr_offset()
|
||||
// In os_cpu .ad file
|
||||
// int MachCallRuntimeNode::ret_addr_offset()
|
||||
|
||||
// Indicate if the safepoint node needs the polling page as an input.
|
||||
// Since amd64 does not have absolute addressing but RIP-relative
|
||||
// addressing and the polling page is within 2G, it doesn't.
|
||||
// Indicate if the safepoint node needs the polling page as an input,
|
||||
// it does if the polling page is more than disp32 away.
|
||||
bool SafePointNode::needs_polling_address_input()
|
||||
{
|
||||
return false;
|
||||
return Assembler::is_polling_page_far();
|
||||
}
|
||||
|
||||
//
|
||||
@ -992,15 +991,21 @@ void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
||||
framesize -= 2*wordSize;
|
||||
|
||||
if (framesize) {
|
||||
st->print_cr("addq\trsp, %d\t# Destroy frame", framesize);
|
||||
st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
|
||||
st->print("\t");
|
||||
}
|
||||
|
||||
st->print_cr("popq\trbp");
|
||||
st->print_cr("popq rbp");
|
||||
if (do_polling() && C->is_method_compilation()) {
|
||||
st->print_cr("\ttestl\trax, [rip + #offset_to_poll_page]\t"
|
||||
"# Safepoint: poll for GC");
|
||||
st->print("\t");
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
st->print_cr("movq rscratch1, #polling_page_address\n\t"
|
||||
"testl rax, [rscratch1]\t"
|
||||
"# Safepoint: poll for GC");
|
||||
} else {
|
||||
st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
|
||||
"# Safepoint: poll for GC");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1033,45 +1038,22 @@ void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
||||
emit_opcode(cbuf, 0x58 | RBP_enc);
|
||||
|
||||
if (do_polling() && C->is_method_compilation()) {
|
||||
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
|
||||
// XXX reg_mem doesn't support RIP-relative addressing yet
|
||||
cbuf.set_insts_mark();
|
||||
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_return_type, 0); // XXX
|
||||
emit_opcode(cbuf, 0x85); // testl
|
||||
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
|
||||
// cbuf.insts_mark() is beginning of instruction
|
||||
emit_d32_reloc(cbuf, os::get_polling_page());
|
||||
// relocInfo::poll_return_type,
|
||||
MacroAssembler _masm(&cbuf);
|
||||
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
|
||||
if (Assembler::is_polling_page_far()) {
|
||||
__ lea(rscratch1, polling_page);
|
||||
__ relocate(relocInfo::poll_return_type);
|
||||
__ testl(rax, Address(rscratch1, 0));
|
||||
} else {
|
||||
__ testl(rax, polling_page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
|
||||
{
|
||||
Compile* C = ra_->C;
|
||||
int framesize = C->frame_slots() << LogBytesPerInt;
|
||||
assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
|
||||
// Remove word for return adr already pushed
|
||||
// and RBP
|
||||
framesize -= 2*wordSize;
|
||||
|
||||
uint size = 0;
|
||||
|
||||
if (do_polling() && C->is_method_compilation()) {
|
||||
size += 6;
|
||||
}
|
||||
|
||||
// count popq rbp
|
||||
size++;
|
||||
|
||||
if (framesize) {
|
||||
if (framesize < 0x80) {
|
||||
size += 4;
|
||||
} else if (framesize) {
|
||||
size += 7;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
return MachNode::size(ra_); // too many variables; just compute it
|
||||
// the hard way
|
||||
}
|
||||
|
||||
int MachEpilogNode::reloc() const
|
||||
@ -2000,6 +1982,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong;
|
||||
// into registers? True for Intel but false for most RISCs
|
||||
const bool Matcher::clone_shift_expressions = true;
|
||||
|
||||
// Do we need to mask the count passed to shift instructions or does
|
||||
// the cpu only look at the lower 5/6 bits anyway?
|
||||
const bool Matcher::need_masked_shift_count = false;
|
||||
|
||||
bool Matcher::narrow_oop_use_complex_address() {
|
||||
assert(UseCompressedOops, "only for compressed oops code");
|
||||
return (LogMinObjAlignmentInBytes <= 3);
|
||||
@ -3406,8 +3392,8 @@ encode %{
|
||||
}
|
||||
if (EmitSync & 1) {
|
||||
// Without cast to int32_t a movptr will destroy r10 which is typically obj
|
||||
masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
|
||||
masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
|
||||
masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
|
||||
masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
|
||||
} else
|
||||
if (EmitSync & 2) {
|
||||
Label DONE_LABEL;
|
||||
@ -3435,10 +3421,10 @@ encode %{
|
||||
} else {
|
||||
Label DONE_LABEL, IsInflated, Egress;
|
||||
|
||||
masm.movptr(tmpReg, Address(objReg, 0)) ;
|
||||
masm.movptr(tmpReg, Address(objReg, 0)) ;
|
||||
masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased
|
||||
masm.jcc (Assembler::notZero, IsInflated) ;
|
||||
|
||||
masm.jcc (Assembler::notZero, IsInflated) ;
|
||||
|
||||
// it's stack-locked, biased or neutral
|
||||
// TODO: optimize markword triage order to reduce the number of
|
||||
// conditional branches in the most common cases.
|
||||
@ -3452,9 +3438,9 @@ encode %{
|
||||
}
|
||||
|
||||
// was q will it destroy high?
|
||||
masm.orl (tmpReg, 1) ;
|
||||
masm.movptr(Address(boxReg, 0), tmpReg) ;
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.orl (tmpReg, 1) ;
|
||||
masm.movptr(Address(boxReg, 0), tmpReg) ;
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
|
||||
if (_counters != NULL) {
|
||||
masm.cond_inc32(Assembler::equal,
|
||||
@ -3481,16 +3467,16 @@ encode %{
|
||||
// fetched _owner. If the CAS is successful we may
|
||||
// avoid an RTO->RTS upgrade on the $line.
|
||||
// Without cast to int32_t a movptr will destroy r10 which is typically obj
|
||||
masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
|
||||
masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
|
||||
|
||||
masm.mov (boxReg, tmpReg) ;
|
||||
masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
masm.testptr(tmpReg, tmpReg) ;
|
||||
masm.jcc (Assembler::notZero, DONE_LABEL) ;
|
||||
masm.mov (boxReg, tmpReg) ;
|
||||
masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
masm.testptr(tmpReg, tmpReg) ;
|
||||
masm.jcc (Assembler::notZero, DONE_LABEL) ;
|
||||
|
||||
// It's inflated and appears unlocked
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
// Intentional fall-through into DONE_LABEL ...
|
||||
|
||||
masm.bind (DONE_LABEL) ;
|
||||
@ -3509,8 +3495,8 @@ encode %{
|
||||
Register tmpReg = as_Register($tmp$$reg);
|
||||
MacroAssembler masm(&cbuf);
|
||||
|
||||
if (EmitSync & 4) {
|
||||
masm.cmpptr(rsp, 0) ;
|
||||
if (EmitSync & 4) {
|
||||
masm.cmpptr(rsp, 0) ;
|
||||
} else
|
||||
if (EmitSync & 8) {
|
||||
Label DONE_LABEL;
|
||||
@ -3537,25 +3523,25 @@ encode %{
|
||||
if (UseBiasedLocking && !UseOptoBiasInlining) {
|
||||
masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
|
||||
}
|
||||
|
||||
masm.movptr(tmpReg, Address(objReg, 0)) ;
|
||||
masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
|
||||
masm.jcc (Assembler::zero, DONE_LABEL) ;
|
||||
masm.testl (tmpReg, 0x02) ;
|
||||
masm.jcc (Assembler::zero, Stacked) ;
|
||||
|
||||
|
||||
masm.movptr(tmpReg, Address(objReg, 0)) ;
|
||||
masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
|
||||
masm.jcc (Assembler::zero, DONE_LABEL) ;
|
||||
masm.testl (tmpReg, 0x02) ;
|
||||
masm.jcc (Assembler::zero, Stacked) ;
|
||||
|
||||
// It's inflated
|
||||
masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
masm.xorptr(boxReg, r15_thread) ;
|
||||
masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
|
||||
masm.jcc (Assembler::notZero, DONE_LABEL) ;
|
||||
masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
|
||||
masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
|
||||
masm.jcc (Assembler::notZero, CheckSucc) ;
|
||||
masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
|
||||
masm.jmp (DONE_LABEL) ;
|
||||
|
||||
if ((EmitSync & 65536) == 0) {
|
||||
masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
|
||||
masm.xorptr(boxReg, r15_thread) ;
|
||||
masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
|
||||
masm.jcc (Assembler::notZero, DONE_LABEL) ;
|
||||
masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
|
||||
masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
|
||||
masm.jcc (Assembler::notZero, CheckSucc) ;
|
||||
masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
|
||||
masm.jmp (DONE_LABEL) ;
|
||||
|
||||
if ((EmitSync & 65536) == 0) {
|
||||
Label LSuccess, LGoSlowPath ;
|
||||
masm.bind (CheckSucc) ;
|
||||
masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
|
||||
@ -3587,9 +3573,9 @@ encode %{
|
||||
masm.jmp (DONE_LABEL) ;
|
||||
}
|
||||
|
||||
masm.bind (Stacked) ;
|
||||
masm.bind (Stacked) ;
|
||||
masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
if (os::is_MP()) { masm.lock(); }
|
||||
masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
|
||||
|
||||
if (EmitSync & 65536) {
|
||||
@ -3910,22 +3896,6 @@ encode %{
|
||||
|
||||
// done:
|
||||
%}
|
||||
|
||||
// Safepoint Poll. This polls the safepoint page, and causes an
|
||||
// exception if it is not readable. Unfortunately, it kills
|
||||
// RFLAGS in the process.
|
||||
enc_class enc_safepoint_poll
|
||||
%{
|
||||
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
|
||||
// XXX reg_mem doesn't support RIP-relative addressing yet
|
||||
cbuf.set_insts_mark();
|
||||
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); // XXX
|
||||
emit_opcode(cbuf, 0x85); // testl
|
||||
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
|
||||
// cbuf.insts_mark() is beginning of instruction
|
||||
emit_d32_reloc(cbuf, os::get_polling_page());
|
||||
// relocInfo::poll_type,
|
||||
%}
|
||||
%}
|
||||
|
||||
|
||||
@ -4229,6 +4199,15 @@ operand immP0()
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
operand immP_poll() %{
|
||||
predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
|
||||
match(ConP);
|
||||
|
||||
// formats are generated automatically for constants and base registers
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Pointer Immediate
|
||||
operand immN() %{
|
||||
match(ConN);
|
||||
@ -4836,7 +4815,7 @@ operand regF()
|
||||
%}
|
||||
|
||||
// Double register operands
|
||||
operand regD()
|
||||
operand regD()
|
||||
%{
|
||||
constraint(ALLOC_IN_RC(double_reg));
|
||||
match(RegD);
|
||||
@ -6564,6 +6543,16 @@ instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct loadConP_poll(rRegP dst, immP_poll src) %{
|
||||
match(Set dst src);
|
||||
format %{ "movq $dst, $src\t!ptr" %}
|
||||
ins_encode %{
|
||||
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
|
||||
__ lea($dst$$Register, polling_page);
|
||||
%}
|
||||
ins_pipe(ialu_reg_fat);
|
||||
%}
|
||||
|
||||
instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst src);
|
||||
@ -7237,11 +7226,11 @@ instruct bytes_reverse_long(rRegL dst) %{
|
||||
instruct bytes_reverse_unsigned_short(rRegI dst) %{
|
||||
match(Set dst (ReverseBytesUS dst));
|
||||
|
||||
format %{ "bswapl $dst\n\t"
|
||||
format %{ "bswapl $dst\n\t"
|
||||
"shrl $dst,16\n\t" %}
|
||||
ins_encode %{
|
||||
__ bswapl($dst$$Register);
|
||||
__ shrl($dst$$Register, 16);
|
||||
__ shrl($dst$$Register, 16);
|
||||
%}
|
||||
ins_pipe( ialu_reg );
|
||||
%}
|
||||
@ -7249,11 +7238,11 @@ instruct bytes_reverse_unsigned_short(rRegI dst) %{
|
||||
instruct bytes_reverse_short(rRegI dst) %{
|
||||
match(Set dst (ReverseBytesS dst));
|
||||
|
||||
format %{ "bswapl $dst\n\t"
|
||||
format %{ "bswapl $dst\n\t"
|
||||
"sar $dst,16\n\t" %}
|
||||
ins_encode %{
|
||||
__ bswapl($dst$$Register);
|
||||
__ sarl($dst$$Register, 16);
|
||||
__ sarl($dst$$Register, 16);
|
||||
%}
|
||||
ins_pipe( ialu_reg );
|
||||
%}
|
||||
@ -7476,7 +7465,7 @@ instruct membar_volatile(rFlagsReg cr) %{
|
||||
effect(KILL cr);
|
||||
ins_cost(400);
|
||||
|
||||
format %{
|
||||
format %{
|
||||
$$template
|
||||
if (os::is_MP()) {
|
||||
$$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
|
||||
@ -8287,7 +8276,7 @@ instruct storePConditional(memory heap_top_ptr,
|
||||
rFlagsReg cr)
|
||||
%{
|
||||
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
|
||||
|
||||
|
||||
format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
|
||||
"If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
|
||||
opcode(0x0F, 0xB1);
|
||||
@ -9850,9 +9839,9 @@ instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
|
||||
|
||||
// Xor Register with Immediate -1
|
||||
instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
|
||||
match(Set dst (XorI dst imm));
|
||||
match(Set dst (XorI dst imm));
|
||||
|
||||
format %{ "not $dst" %}
|
||||
format %{ "not $dst" %}
|
||||
ins_encode %{
|
||||
__ notl($dst$$Register);
|
||||
%}
|
||||
@ -10093,9 +10082,9 @@ instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
|
||||
|
||||
// Xor Register with Immediate -1
|
||||
instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
|
||||
match(Set dst (XorL dst imm));
|
||||
match(Set dst (XorL dst imm));
|
||||
|
||||
format %{ "notq $dst" %}
|
||||
format %{ "notq $dst" %}
|
||||
ins_encode %{
|
||||
__ notq($dst$$Register);
|
||||
%}
|
||||
@ -12469,14 +12458,33 @@ instruct cmpFastUnlock(rFlagsReg cr,
|
||||
// Safepoint Instructions
|
||||
instruct safePoint_poll(rFlagsReg cr)
|
||||
%{
|
||||
predicate(!Assembler::is_polling_page_far());
|
||||
match(SafePoint);
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "testl rax, [rip + #offset_to_poll_page]\t"
|
||||
format %{ "testl rax, [rip + #offset_to_poll_page]\t"
|
||||
"# Safepoint: poll for GC" %}
|
||||
size(6); // Opcode + ModRM + Disp32 == 6 bytes
|
||||
ins_cost(125);
|
||||
ins_encode(enc_safepoint_poll);
|
||||
ins_encode %{
|
||||
AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
|
||||
__ testl(rax, addr);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
|
||||
%{
|
||||
predicate(Assembler::is_polling_page_far());
|
||||
match(SafePoint poll);
|
||||
effect(KILL cr, USE poll);
|
||||
|
||||
format %{ "testl rax, [$poll]\t"
|
||||
"# Safepoint: poll for GC" %}
|
||||
ins_cost(125);
|
||||
ins_encode %{
|
||||
__ relocate(relocInfo::poll_type);
|
||||
__ testl(rax, Address($poll$$Register, 0));
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
|
@ -47,18 +47,6 @@ public class Util {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static String join(String padder, String v[]) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for (int i=0; i<v.length; i++) {
|
||||
sb.append(v[i]);
|
||||
if (i < (v.length - 1)) sb.append(padder);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static String prefixed_join(String padder, Vector v, boolean quoted) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
@ -587,7 +587,6 @@ public abstract class WinGammaPlatform {
|
||||
Vector allConfigs = new Vector();
|
||||
|
||||
allConfigs.add(new C1DebugConfig());
|
||||
|
||||
allConfigs.add(new C1FastDebugConfig());
|
||||
allConfigs.add(new C1ProductConfig());
|
||||
|
||||
@ -655,6 +654,10 @@ public abstract class WinGammaPlatform {
|
||||
boolean isHeader() {
|
||||
return attr.shortName.endsWith(".h") || attr.shortName.endsWith(".hpp");
|
||||
}
|
||||
|
||||
boolean isCpp() {
|
||||
return attr.shortName.endsWith(".cpp");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -708,7 +711,7 @@ public abstract class WinGammaPlatform {
|
||||
PrintWriter printWriter;
|
||||
|
||||
public void writeProjectFile(String projectFileName, String projectName,
|
||||
Vector allConfigs) throws IOException {
|
||||
Vector<BuildConfig> allConfigs) throws IOException {
|
||||
throw new RuntimeException("use compiler version specific version");
|
||||
}
|
||||
}
|
||||
|
545
hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
Normal file
545
hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
Normal file
@ -0,0 +1,545 @@
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.Vector;
|
||||
|
||||
public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
|
||||
|
||||
@Override
|
||||
protected String getProjectExt() {
|
||||
return ".vcxproj";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeProjectFile(String projectFileName, String projectName,
|
||||
Vector<BuildConfig> allConfigs) throws IOException {
|
||||
System.out.println();
|
||||
System.out.print(" Writing .vcxproj file: " + projectFileName);
|
||||
|
||||
String projDir = Util.normalize(new File(projectFileName).getParent());
|
||||
|
||||
printWriter = new PrintWriter(projectFileName, "UTF-8");
|
||||
printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
startTag("Project",
|
||||
"DefaultTargets", "Build",
|
||||
"ToolsVersion", "4.0",
|
||||
"xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
startTag("ItemGroup",
|
||||
"Label", "ProjectConfigurations");
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag("ProjectConfiguration",
|
||||
"Include", cfg.get("Name"));
|
||||
tagData("Configuration", cfg.get("Id"));
|
||||
tagData("Platform", cfg.get("PlatformName"));
|
||||
endTag("ProjectConfiguration");
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
startTag("PropertyGroup", "Label", "Globals");
|
||||
tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}");
|
||||
tag("SccProjectName");
|
||||
tag("SccLocalPath");
|
||||
endTag("PropertyGroup");
|
||||
|
||||
tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
|
||||
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag(cfg, "PropertyGroup", "Label", "Configuration");
|
||||
tagData("ConfigurationType", "DynamicLibrary");
|
||||
tagData("UseOfMfc", "false");
|
||||
endTag("PropertyGroup");
|
||||
}
|
||||
|
||||
tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props");
|
||||
startTag("ImportGroup", "Label", "ExtensionSettings");
|
||||
endTag("ImportGroup");
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag(cfg, "ImportGroup", "Label", "PropertySheets");
|
||||
tag("Import",
|
||||
"Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props",
|
||||
"Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')",
|
||||
"Label", "LocalAppDataPlatform");
|
||||
endTag("ImportGroup");
|
||||
}
|
||||
|
||||
tag("PropertyGroup", "Label", "UserMacros");
|
||||
|
||||
startTag("PropertyGroup");
|
||||
tagData("_ProjectFileVersion", "10.0.30319.1");
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
tagData(cfg, "OutDir", cfg.get("OutputDir") + Util.sep);
|
||||
tagData(cfg, "IntDir", cfg.get("OutputDir") + Util.sep);
|
||||
tagData(cfg, "LinkIncremental", "false");
|
||||
}
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
tagData(cfg, "CodeAnalysisRuleSet", "AllRules.ruleset");
|
||||
tag(cfg, "CodeAnalysisRules");
|
||||
tag(cfg, "CodeAnalysisRuleAssemblies");
|
||||
}
|
||||
endTag("PropertyGroup");
|
||||
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag(cfg, "ItemDefinitionGroup");
|
||||
startTag("ClCompile");
|
||||
tagV(cfg.getV("CompilerFlags"));
|
||||
endTag("ClCompile");
|
||||
|
||||
startTag("Link");
|
||||
tagV(cfg.getV("LinkerFlags"));
|
||||
endTag("Link");
|
||||
|
||||
startTag("PostBuildEvent");
|
||||
tagData("Message", BuildConfig.getFieldString(null, "PostbuildDescription"));
|
||||
tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace("\t", "\r\n")));
|
||||
endTag("PostBuildEvent");
|
||||
|
||||
startTag("PreLinkEvent");
|
||||
tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription"));
|
||||
tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n")));
|
||||
endTag("PreLinkEvent");
|
||||
|
||||
endTag("ItemDefinitionGroup");
|
||||
}
|
||||
|
||||
writeFiles(allConfigs, projDir);
|
||||
|
||||
tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
|
||||
startTag("ImportGroup", "Label", "ExtensionTargets");
|
||||
endTag("ImportGroup");
|
||||
|
||||
endTag("Project");
|
||||
printWriter.close();
|
||||
System.out.println(" Done.");
|
||||
|
||||
writeFilterFile(projectFileName, projectName, allConfigs, projDir);
|
||||
writeUserFile(projectFileName, allConfigs);
|
||||
}
|
||||
|
||||
|
||||
private void writeUserFile(String projectFileName, Vector<BuildConfig> allConfigs) throws FileNotFoundException, UnsupportedEncodingException {
|
||||
String userFileName = projectFileName + ".user";
|
||||
if (new File(userFileName).exists()) {
|
||||
return;
|
||||
}
|
||||
System.out.print(" Writing .vcxproj.user file: " + userFileName);
|
||||
printWriter = new PrintWriter(userFileName, "UTF-8");
|
||||
|
||||
printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
startTag("Project",
|
||||
"ToolsVersion", "4.0",
|
||||
"xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
startTag(cfg, "PropertyGroup");
|
||||
tagData("LocalDebuggerCommand", "$(TargetDir)/hotspot.exe");
|
||||
endTag("PropertyGroup");
|
||||
}
|
||||
|
||||
endTag("Project");
|
||||
printWriter.close();
|
||||
System.out.println(" Done.");
|
||||
}
|
||||
|
||||
private void writeFilterFile(String projectFileName, String projectName,
|
||||
Vector<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException {
|
||||
String filterFileName = projectFileName + ".filters";
|
||||
System.out.print(" Writing .vcxproj.filters file: " + filterFileName);
|
||||
printWriter = new PrintWriter(filterFileName, "UTF-8");
|
||||
|
||||
printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
startTag("Project",
|
||||
"ToolsVersion", "4.0",
|
||||
"xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
|
||||
Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs);
|
||||
TreeSet<FileInfo> sortedFiles = sortFiles(allFiles);
|
||||
Vector<NameFilter> filters = makeFilters(sortedFiles);
|
||||
|
||||
// first all filters
|
||||
startTag("ItemGroup");
|
||||
for (NameFilter filter : filters) {
|
||||
doWriteFilter(filter, "");
|
||||
}
|
||||
startTag("Filter", "Include", "Resource Files");
|
||||
UUID uuid = UUID.randomUUID();
|
||||
tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
|
||||
tagData("Extensions", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe");
|
||||
endTag("Filter");
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then all cpp files
|
||||
startTag("ItemGroup");
|
||||
for (NameFilter filter : filters) {
|
||||
doWriteFiles(sortedFiles, filter, "", "ClCompile", new Evaluator() {
|
||||
public boolean pick(FileInfo fi) {
|
||||
return fi.isCpp();
|
||||
}
|
||||
}, base);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then all header files
|
||||
startTag("ItemGroup");
|
||||
for (NameFilter filter : filters) {
|
||||
doWriteFiles(sortedFiles, filter, "", "ClInclude", new Evaluator() {
|
||||
public boolean pick(FileInfo fi) {
|
||||
return fi.isHeader();
|
||||
}
|
||||
}, base);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then all other files
|
||||
startTag("ItemGroup");
|
||||
for (NameFilter filter : filters) {
|
||||
doWriteFiles(sortedFiles, filter, "", "None", new Evaluator() {
|
||||
public boolean pick(FileInfo fi) {
|
||||
return true;
|
||||
}
|
||||
}, base);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
endTag("Project");
|
||||
printWriter.close();
|
||||
System.out.println(" Done.");
|
||||
}
|
||||
|
||||
|
||||
private void doWriteFilter(NameFilter filter, String start) {
|
||||
startTag("Filter", "Include", start + filter.fname);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
|
||||
endTag("Filter");
|
||||
if (filter instanceof ContainerFilter) {
|
||||
Iterator i = ((ContainerFilter)filter).babies();
|
||||
while (i.hasNext()) {
|
||||
doWriteFilter((NameFilter)i.next(), start + filter.fname + "\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Evaluator {
|
||||
boolean pick(FileInfo fi);
|
||||
}
|
||||
|
||||
private void doWriteFiles(TreeSet<FileInfo> allFiles, NameFilter filter, String start, String tool, Evaluator eval, String base) {
|
||||
if (filter instanceof ContainerFilter) {
|
||||
Iterator i = ((ContainerFilter)filter).babies();
|
||||
while (i.hasNext()) {
|
||||
doWriteFiles(allFiles, (NameFilter)i.next(), start + filter.fname + "\\", tool, eval, base);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Iterator i = allFiles.iterator();
|
||||
while (i.hasNext()) {
|
||||
FileInfo fi = (FileInfo)i.next();
|
||||
|
||||
if (!filter.match(fi)) {
|
||||
continue;
|
||||
}
|
||||
if (eval.pick(fi)) {
|
||||
startTag(tool, "Include", rel(fi.full, base));
|
||||
tagData("Filter", start + filter.fname);
|
||||
endTag(tool);
|
||||
|
||||
// we not gonna look at this file anymore (sic!)
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writeFiles(Vector<BuildConfig> allConfigs, String projDir) {
|
||||
Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs);
|
||||
TreeSet<FileInfo> sortedFiles = sortFiles(allFiles);
|
||||
|
||||
// first cpp-files
|
||||
startTag("ItemGroup");
|
||||
for (FileInfo fi : sortedFiles) {
|
||||
if (!fi.isCpp()) {
|
||||
continue;
|
||||
}
|
||||
writeFile("ClCompile", allConfigs, fi, projDir);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then header-files
|
||||
startTag("ItemGroup");
|
||||
for (FileInfo fi : sortedFiles) {
|
||||
if (!fi.isHeader()) {
|
||||
continue;
|
||||
}
|
||||
writeFile("ClInclude", allConfigs, fi, projDir);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
|
||||
// then others
|
||||
startTag("ItemGroup");
|
||||
for (FileInfo fi : sortedFiles) {
|
||||
if (fi.isHeader() || fi.isCpp()) {
|
||||
continue;
|
||||
}
|
||||
writeFile("None", allConfigs, fi, projDir);
|
||||
}
|
||||
endTag("ItemGroup");
|
||||
}
|
||||
|
||||
/**
|
||||
* Make "path" into a relative path using "base" as the base.
|
||||
*
|
||||
* path and base are assumed to be normalized with / as the file separator.
|
||||
* returned path uses "\\" as file separator
|
||||
*/
|
||||
private String rel(String path, String base)
|
||||
{
|
||||
if(!base.endsWith("/")) {
|
||||
base += "/";
|
||||
}
|
||||
String[] pathTok = path.split("/");
|
||||
String[] baseTok = base.split("/");
|
||||
int pi = 0;
|
||||
int bi = 0;
|
||||
StringBuilder newPath = new StringBuilder();
|
||||
|
||||
// first step past all path components that are the same
|
||||
while (pi < pathTok.length &&
|
||||
bi < baseTok.length &&
|
||||
pathTok[pi].equals(baseTok[bi])) {
|
||||
pi++;
|
||||
bi++;
|
||||
}
|
||||
|
||||
// for each path component left in base, add "../"
|
||||
while (bi < baseTok.length) {
|
||||
bi++;
|
||||
newPath.append("..\\");
|
||||
}
|
||||
|
||||
// now add everything left in path
|
||||
while (pi < pathTok.length) {
|
||||
newPath.append(pathTok[pi]);
|
||||
pi++;
|
||||
if (pi != pathTok.length) {
|
||||
newPath.append("\\");
|
||||
}
|
||||
}
|
||||
return newPath.toString();
|
||||
}
|
||||
|
||||
private void writeFile(String tool, Vector<BuildConfig> allConfigs, FileInfo fi, String base) {
|
||||
if (fi.attr.configs == null && fi.attr.pchRoot == false && fi.attr.noPch == false) {
|
||||
tag(tool, "Include", rel(fi.full, base));
|
||||
}
|
||||
else {
|
||||
startTag(tool, "Include", rel(fi.full, base));
|
||||
for (BuildConfig cfg : allConfigs) {
|
||||
if (fi.attr.configs != null && !fi.attr.configs.contains(cfg.get("Name"))) {
|
||||
tagData(cfg, "ExcludedFromBuild", "true");
|
||||
}
|
||||
if (fi.attr.pchRoot) {
|
||||
tagData(cfg, "PrecompiledHeader", "Create");
|
||||
}
|
||||
if (fi.attr.noPch) {
|
||||
startTag(cfg, "PrecompiledHeader");
|
||||
endTag("PrecompiledHeader");
|
||||
}
|
||||
}
|
||||
endTag(tool);
|
||||
}
|
||||
}
|
||||
|
||||
String buildCond(BuildConfig cfg) {
|
||||
return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'";
|
||||
}
|
||||
|
||||
|
||||
void tagV(Vector<String> v) {
|
||||
Iterator<String> i = v.iterator();
|
||||
while(i.hasNext()) {
|
||||
String name = i.next();
|
||||
String data = i.next();
|
||||
tagData(name, data);
|
||||
}
|
||||
}
|
||||
|
||||
void tagData(BuildConfig cfg, String name, String data) {
|
||||
tagData(name, data, "Condition", buildCond(cfg));
|
||||
}
|
||||
|
||||
void tag(BuildConfig cfg, String name, String... attrs) {
|
||||
String[] ss = new String[attrs.length + 2];
|
||||
ss[0] = "Condition";
|
||||
ss[1] = buildCond(cfg);
|
||||
System.arraycopy(attrs, 0, ss, 2, attrs.length);
|
||||
|
||||
tag(name, ss);
|
||||
}
|
||||
|
||||
void startTag(BuildConfig cfg, String name, String... attrs) {
|
||||
String[] ss = new String[attrs.length + 2];
|
||||
ss[0] = "Condition";
|
||||
ss[1] = buildCond(cfg);
|
||||
System.arraycopy(attrs, 0, ss, 2, attrs.length);
|
||||
|
||||
startTag(name, ss);
|
||||
}
|
||||
}
|
||||
|
||||
class CompilerInterfaceVC10 extends CompilerInterface {
|
||||
|
||||
@Override
|
||||
Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
|
||||
Vector rv = new Vector();
|
||||
|
||||
addAttr(rv, "AdditionalIncludeDirectories", Util.join(";", includes));
|
||||
addAttr(rv, "PreprocessorDefinitions",
|
||||
Util.join(";", defines).replace("\\\"", "\""));
|
||||
addAttr(rv, "PrecompiledHeaderFile", "precompiled.hpp");
|
||||
addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch");
|
||||
addAttr(rv, "AssemblerListingLocation", outDir);
|
||||
addAttr(rv, "ObjectFileName", outDir+Util.sep);
|
||||
addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb");
|
||||
// Set /nologo option
|
||||
addAttr(rv, "SuppressStartupBanner", "true");
|
||||
// Surpass the default /Tc or /Tp.
|
||||
addAttr(rv, "CompileAs", "Default");
|
||||
// Set /W3 option.
|
||||
addAttr(rv, "WarningLevel", "Level3");
|
||||
// Set /WX option,
|
||||
addAttr(rv, "TreatWarningAsError", "true");
|
||||
// Set /GS option
|
||||
addAttr(rv, "BufferSecurityCheck", "false");
|
||||
// Set /Zi option.
|
||||
addAttr(rv, "DebugInformationFormat", "ProgramDatabase");
|
||||
// Set /Yu option.
|
||||
addAttr(rv, "PrecompiledHeader", "Use");
|
||||
// Set /EHsc- option
|
||||
addAttr(rv, "ExceptionHandling", "");
|
||||
|
||||
addAttr(rv, "MultiProcessorCompilation", "true");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getDebugCompilerFlags(String opt) {
|
||||
Vector rv = new Vector();
|
||||
|
||||
// Set /On option
|
||||
addAttr(rv, "Optimization", opt);
|
||||
// Set /FR option.
|
||||
addAttr(rv, "BrowseInformation", "true");
|
||||
addAttr(rv, "BrowseInformationFile", "$(IntDir)");
|
||||
// Set /MD option.
|
||||
addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
|
||||
// Set /Oy- option
|
||||
addAttr(rv, "OmitFramePointers", "false");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getProductCompilerFlags() {
|
||||
Vector rv = new Vector();
|
||||
|
||||
// Set /O2 option.
|
||||
addAttr(rv, "Optimization", "MaxSpeed");
|
||||
// Set /Oy- option
|
||||
addAttr(rv, "OmitFramePointers", "false");
|
||||
// Set /Ob option. 1 is expandOnlyInline
|
||||
addAttr(rv, "InlineFunctionExpansion", "OnlyExplicitInline");
|
||||
// Set /GF option.
|
||||
addAttr(rv, "StringPooling", "true");
|
||||
// Set /MD option. 2 is rtMultiThreadedDLL
|
||||
addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
|
||||
// Set /Gy option
|
||||
addAttr(rv, "FunctionLevelLinking", "true");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
|
||||
Vector rv = new Vector();
|
||||
|
||||
addAttr(rv, "AdditionalOptions",
|
||||
"/export:JNI_GetDefaultJavaVMInitArgs " +
|
||||
"/export:JNI_CreateJavaVM " +
|
||||
"/export:JVM_FindClassFromBootLoader "+
|
||||
"/export:JNI_GetCreatedJavaVMs "+
|
||||
"/export:jio_snprintf /export:jio_printf "+
|
||||
"/export:jio_fprintf /export:jio_vfprintf "+
|
||||
"/export:jio_vsnprintf "+
|
||||
"/export:JVM_GetVersionInfo "+
|
||||
"/export:JVM_GetThreadStateNames "+
|
||||
"/export:JVM_GetThreadStateValues "+
|
||||
"/export:JVM_InitAgentProperties");
|
||||
addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib");
|
||||
addAttr(rv, "OutputFile", outDll);
|
||||
addAttr(rv, "SuppressStartupBanner", "true");
|
||||
addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
|
||||
addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb");
|
||||
addAttr(rv, "SubSystem", "Windows");
|
||||
addAttr(rv, "BaseAddress", "0x8000000");
|
||||
addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
|
||||
|
||||
if(platformName.equals("Win32")) {
|
||||
addAttr(rv, "TargetMachine", "MachineX86");
|
||||
} else {
|
||||
addAttr(rv, "TargetMachine", "MachineX64");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getDebugLinkerFlags() {
|
||||
Vector rv = new Vector();
|
||||
|
||||
// /DEBUG option
|
||||
addAttr(rv, "GenerateDebugInformation", "true");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
Vector getProductLinkerFlags() {
|
||||
Vector rv = new Vector();
|
||||
|
||||
// Set /OPT:REF option.
|
||||
addAttr(rv, "OptimizeReferences", "true");
|
||||
// Set /OPT:ICF option.
|
||||
addAttr(rv, "EnableCOMDATFolding", "true");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@Override
|
||||
void getAdditionalNonKernelLinkerFlags(Vector rv) {
|
||||
extAttr(rv, "AdditionalOptions", " /export:AsyncGetCallTrace");
|
||||
}
|
||||
|
||||
@Override
|
||||
String getOptFlag() {
|
||||
return "MaxSpeed";
|
||||
}
|
||||
|
||||
@Override
|
||||
String getNoOptFlag() {
|
||||
return "Disabled";
|
||||
}
|
||||
|
||||
@Override
|
||||
String makeCfgName(String flavourBuild, String platform) {
|
||||
return flavourBuild + "|" + platform;
|
||||
}
|
||||
|
||||
}
|
@ -35,7 +35,7 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
String projectVersion() {return "7.10";};
|
||||
|
||||
public void writeProjectFile(String projectFileName, String projectName,
|
||||
Vector allConfigs) throws IOException {
|
||||
Vector<BuildConfig> allConfigs) throws IOException {
|
||||
System.out.println();
|
||||
System.out.println(" Writing .vcproj file: "+projectFileName);
|
||||
// If we got this far without an error, we're safe to actually
|
||||
@ -54,11 +54,11 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
"SccLocalPath", ""
|
||||
}
|
||||
);
|
||||
startTag("Platforms", null);
|
||||
startTag("Platforms");
|
||||
tag("Platform", new String[] {"Name", (String) BuildConfig.getField(null, "PlatformName")});
|
||||
endTag("Platforms");
|
||||
|
||||
startTag("Configurations", null);
|
||||
startTag("Configurations");
|
||||
|
||||
for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
|
||||
writeConfiguration((BuildConfig)i.next());
|
||||
@ -66,11 +66,11 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
|
||||
endTag("Configurations");
|
||||
|
||||
tag("References", null);
|
||||
tag("References");
|
||||
|
||||
writeFiles(allConfigs);
|
||||
|
||||
tag("Globals", null);
|
||||
tag("Globals");
|
||||
|
||||
endTag("VisualStudioProject");
|
||||
printWriter.close();
|
||||
@ -190,28 +190,6 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
class TypeFilter extends NameFilter {
|
||||
String[] exts;
|
||||
|
||||
TypeFilter(String fname, String[] exts) {
|
||||
this.fname = fname;
|
||||
this.exts = exts;
|
||||
}
|
||||
|
||||
boolean match(FileInfo fi) {
|
||||
for (int i=0; i<exts.length; i++) {
|
||||
if (fi.full.endsWith(exts[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
String filterString() {
|
||||
return Util.join(";", exts);
|
||||
}
|
||||
}
|
||||
|
||||
class TerminatorFilter extends NameFilter {
|
||||
TerminatorFilter(String fname) {
|
||||
this.fname = fname;
|
||||
@ -299,8 +277,8 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
// - container filter just provides a container to group together real filters
|
||||
// - real filter can select elements from the set according to some rule, put it into XML
|
||||
// and remove from the list
|
||||
Vector makeFilters(TreeSet<FileInfo> files) {
|
||||
Vector rv = new Vector();
|
||||
Vector<NameFilter> makeFilters(TreeSet<FileInfo> files) {
|
||||
Vector<NameFilter> rv = new Vector<NameFilter>();
|
||||
String sbase = Util.normalize(BuildConfig.getFieldString(null, "SourceBase")+"/src/");
|
||||
|
||||
String currentDir = "";
|
||||
@ -370,13 +348,12 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
rv.add(new SpecificNameFilter("Precompiled Header", new String[] {"precompiled.hpp"}));
|
||||
|
||||
// this one is to catch files not caught by other filters
|
||||
//rv.add(new TypeFilter("Header Files", new String[] {"h", "hpp", "hxx", "hm", "inl", "fi", "fd"}));
|
||||
rv.add(new TerminatorFilter("Source Files"));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void writeFiles(Vector allConfigs) {
|
||||
void writeFiles(Vector<BuildConfig> allConfigs) {
|
||||
|
||||
Hashtable allFiles = computeAttributedFiles(allConfigs);
|
||||
|
||||
@ -387,7 +364,7 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
|
||||
TreeSet sortedFiles = sortFiles(allFiles);
|
||||
|
||||
startTag("Files", null);
|
||||
startTag("Files");
|
||||
|
||||
for (Iterator i = makeFilters(sortedFiles).iterator(); i.hasNext(); ) {
|
||||
doWriteFiles(sortedFiles, allConfigNames, (NameFilter)i.next());
|
||||
@ -555,35 +532,40 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
|
||||
int indent;
|
||||
|
||||
private void startTagPrim(String name,
|
||||
String[] attrs,
|
||||
boolean close) {
|
||||
startTagPrim(name, attrs, close, true);
|
||||
}
|
||||
|
||||
private void startTagPrim(String name,
|
||||
String[] attrs,
|
||||
boolean close) {
|
||||
boolean close,
|
||||
boolean newline) {
|
||||
doIndent();
|
||||
printWriter.print("<"+name);
|
||||
indent++;
|
||||
|
||||
if (attrs != null) {
|
||||
printWriter.println();
|
||||
if (attrs != null && attrs.length > 0) {
|
||||
for (int i=0; i<attrs.length; i+=2) {
|
||||
doIndent();
|
||||
printWriter.print(" " + attrs[i]+"=\""+attrs[i+1]+"\"");
|
||||
if (i < attrs.length - 2) {
|
||||
printWriter.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (close) {
|
||||
indent--;
|
||||
//doIndent();
|
||||
printWriter.println("/>");
|
||||
printWriter.print(" />");
|
||||
} else {
|
||||
//doIndent();
|
||||
printWriter.println(">");
|
||||
printWriter.print(">");
|
||||
}
|
||||
if(newline) {
|
||||
printWriter.println();
|
||||
}
|
||||
}
|
||||
|
||||
void startTag(String name, String[] attrs) {
|
||||
void startTag(String name, String... attrs) {
|
||||
startTagPrim(name, attrs, false);
|
||||
}
|
||||
|
||||
@ -601,11 +583,25 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
printWriter.println("</"+name+">");
|
||||
}
|
||||
|
||||
void tag(String name, String[] attrs) {
|
||||
void tag(String name, String... attrs) {
|
||||
startTagPrim(name, attrs, true);
|
||||
}
|
||||
|
||||
void tagV(String name, Vector attrs) {
|
||||
void tagData(String name, String data) {
|
||||
doIndent();
|
||||
printWriter.print("<"+name+">");
|
||||
printWriter.print(data);
|
||||
printWriter.println("</"+name+">");
|
||||
}
|
||||
|
||||
void tagData(String name, String data, String... attrs) {
|
||||
startTagPrim(name, attrs, false, false);
|
||||
printWriter.print(data);
|
||||
printWriter.println("</"+name+">");
|
||||
indent--;
|
||||
}
|
||||
|
||||
void tagV(String name, Vector attrs) {
|
||||
String s[] = new String [attrs.size()];
|
||||
for (int i=0; i<attrs.size(); i++) {
|
||||
s[i] = (String)attrs.elementAt(i);
|
||||
@ -616,7 +612,7 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
|
||||
|
||||
void doIndent() {
|
||||
for (int i=0; i<indent; i++) {
|
||||
printWriter.print(" ");
|
||||
printWriter.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,6 +239,11 @@ int main(int argc, char *argv[])
|
||||
AD.addInclude(AD._CPP_file, "assembler_sparc.inline.hpp");
|
||||
AD.addInclude(AD._CPP_file, "nativeInst_sparc.hpp");
|
||||
AD.addInclude(AD._CPP_file, "vmreg_sparc.inline.hpp");
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_arm
|
||||
AD.addInclude(AD._CPP_file, "assembler_arm.inline.hpp");
|
||||
AD.addInclude(AD._CPP_file, "nativeInst_arm.hpp");
|
||||
AD.addInclude(AD._CPP_file, "vmreg_arm.inline.hpp");
|
||||
#endif
|
||||
AD.addInclude(AD._HPP_file, "memory/allocation.hpp");
|
||||
AD.addInclude(AD._HPP_file, "opto/machnode.hpp");
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "c1/c1_InstructionPrinter.hpp"
|
||||
#include "ci/ciField.hpp"
|
||||
#include "ci/ciKlass.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "interpreter/bytecode.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
@ -3775,24 +3776,7 @@ void GraphBuilder::append_unsafe_CAS(ciMethod* callee) {
|
||||
|
||||
#ifndef PRODUCT
|
||||
void GraphBuilder::print_inline_result(ciMethod* callee, bool res) {
|
||||
const char sync_char = callee->is_synchronized() ? 's' : ' ';
|
||||
const char exception_char = callee->has_exception_handlers() ? '!' : ' ';
|
||||
const char monitors_char = callee->has_monitor_bytecodes() ? 'm' : ' ';
|
||||
tty->print(" %c%c%c ", sync_char, exception_char, monitors_char);
|
||||
for (int i = 0; i < scope()->level(); i++) tty->print(" ");
|
||||
if (res) {
|
||||
tty->print(" ");
|
||||
} else {
|
||||
tty->print("- ");
|
||||
}
|
||||
tty->print("@ %d ", bci());
|
||||
callee->print_short_name();
|
||||
tty->print(" (%d bytes)", callee->code_size());
|
||||
if (_inline_bailout_msg) {
|
||||
tty->print(" %s", _inline_bailout_msg);
|
||||
}
|
||||
tty->cr();
|
||||
|
||||
CompileTask::print_inlining(callee, scope()->level(), bci(), _inline_bailout_msg);
|
||||
if (res && CIPrintMethodCodes) {
|
||||
callee->print_codes();
|
||||
}
|
||||
|
@ -1871,7 +1871,8 @@ void ciTypeFlow::Block::print_value_on(outputStream* st) const {
|
||||
// ------------------------------------------------------------------
|
||||
// ciTypeFlow::Block::print_on
|
||||
void ciTypeFlow::Block::print_on(outputStream* st) const {
|
||||
if ((Verbose || WizardMode)) {
|
||||
if ((Verbose || WizardMode) && (limit() >= 0)) {
|
||||
// Don't print 'dummy' blocks (i.e. blocks with limit() '-1')
|
||||
outer()->method()->print_codes_on(start(), limit(), st);
|
||||
}
|
||||
st->print_cr(" ==================================================== ");
|
||||
|
@ -152,7 +152,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
|
||||
"Class file version does not support constant tag %u in class file %s",
|
||||
tag, CHECK);
|
||||
}
|
||||
if (!EnableMethodHandles) {
|
||||
if (!EnableInvokeDynamic) {
|
||||
classfile_parse_error(
|
||||
"This JVM does not support constant tag %u in class file %s",
|
||||
tag, CHECK);
|
||||
@ -260,7 +260,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
|
||||
verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
|
||||
}
|
||||
|
||||
if (AnonymousClasses && has_cp_patch_at(index)) {
|
||||
if (EnableInvokeDynamic && has_cp_patch_at(index)) {
|
||||
Handle patch = clear_cp_patch_at(index);
|
||||
guarantee_property(java_lang_String::is_instance(patch()),
|
||||
"Illegal utf8 patch at %d in class file %s",
|
||||
@ -443,7 +443,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
int ref_index = cp->method_handle_index_at(index);
|
||||
check_property(
|
||||
valid_cp_range(ref_index, length) &&
|
||||
EnableMethodHandles,
|
||||
EnableInvokeDynamic,
|
||||
"Invalid constant pool index %u in class file %s",
|
||||
ref_index, CHECK_(nullHandle));
|
||||
constantTag tag = cp->tag_at(ref_index);
|
||||
@ -487,7 +487,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
check_property(
|
||||
valid_cp_range(ref_index, length) &&
|
||||
cp->tag_at(ref_index).is_utf8() &&
|
||||
EnableMethodHandles,
|
||||
EnableInvokeDynamic,
|
||||
"Invalid constant pool index %u in class file %s",
|
||||
ref_index, CHECK_(nullHandle));
|
||||
}
|
||||
@ -522,7 +522,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
|
||||
if (_cp_patches != NULL) {
|
||||
// need to treat this_class specially...
|
||||
assert(AnonymousClasses, "");
|
||||
assert(EnableInvokeDynamic, "");
|
||||
int this_class_index;
|
||||
{
|
||||
cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len
|
||||
@ -677,7 +677,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
|
||||
|
||||
void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
|
||||
assert(AnonymousClasses, "");
|
||||
assert(EnableInvokeDynamic, "");
|
||||
BasicType patch_type = T_VOID;
|
||||
switch (cp->tag_at(index).value()) {
|
||||
|
||||
@ -2103,7 +2103,7 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
|
||||
_has_vanilla_constructor = true;
|
||||
}
|
||||
|
||||
if (EnableMethodHandles && (m->is_method_handle_invoke() ||
|
||||
if (EnableInvokeDynamic && (m->is_method_handle_invoke() ||
|
||||
m->is_method_handle_adapter())) {
|
||||
THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
|
||||
"Method handle invokers must be defined internally to the VM", nullHandle);
|
||||
@ -2771,7 +2771,7 @@ void ClassFileParser::java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle c
|
||||
// This is not particularly nice, but since there is no way to express
|
||||
// a native wordSize field in Java, we must do it at this level.
|
||||
|
||||
if (!EnableMethodHandles) return;
|
||||
if (!EnableInvokeDynamic) return;
|
||||
|
||||
int word_sig_index = 0;
|
||||
const int cp_size = cp->length();
|
||||
@ -3191,15 +3191,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
next_nonstatic_field_offset = first_nonstatic_field_offset;
|
||||
|
||||
// adjust the vmentry field declaration in java.lang.invoke.MethodHandle
|
||||
if (EnableMethodHandles && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
|
||||
if (EnableInvokeDynamic && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
|
||||
java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
|
||||
}
|
||||
if (AllowTransitionalJSR292 &&
|
||||
EnableMethodHandles && class_name == vmSymbols::java_dyn_MethodHandle() && class_loader.is_null()) {
|
||||
EnableInvokeDynamic && class_name == vmSymbols::java_dyn_MethodHandle() && class_loader.is_null()) {
|
||||
java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
|
||||
}
|
||||
if (AllowTransitionalJSR292 &&
|
||||
EnableMethodHandles && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
|
||||
EnableInvokeDynamic && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
|
||||
// allow vmentry field in MethodHandleImpl also
|
||||
java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
|
||||
}
|
||||
|
@ -231,11 +231,11 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
|
||||
|
||||
bool is_anonymous() {
|
||||
assert(AnonymousClasses || _host_klass.is_null(), "");
|
||||
assert(EnableInvokeDynamic || _host_klass.is_null(), "");
|
||||
return _host_klass.not_null();
|
||||
}
|
||||
bool has_cp_patch_at(int index) {
|
||||
assert(AnonymousClasses, "");
|
||||
assert(EnableInvokeDynamic, "");
|
||||
assert(index >= 0, "oob");
|
||||
return (_cp_patches != NULL
|
||||
&& index < _cp_patches->length()
|
||||
@ -258,7 +258,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
// constant pool construction, but in later versions they can.
|
||||
// %%% Let's phase out the old is_klass_reference.
|
||||
bool is_klass_reference(constantPoolHandle cp, int index) {
|
||||
return ((LinkWellKnownClasses || AnonymousClasses)
|
||||
return ((LinkWellKnownClasses || EnableInvokeDynamic)
|
||||
? cp->tag_at(index).is_klass_or_reference()
|
||||
: cp->tag_at(index).is_klass_reference());
|
||||
}
|
||||
|
@ -301,6 +301,15 @@ jchar* java_lang_String::as_unicode_string(oop java_string, int& length) {
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int java_lang_String::hash_string(oop java_string) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int offset = java_lang_String::offset(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
|
||||
if (length == 0) return 0;
|
||||
return hash_string(value->char_at_addr(offset), length);
|
||||
}
|
||||
|
||||
Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) {
|
||||
oop obj = java_string();
|
||||
typeArrayOop value = java_lang_String::value(obj);
|
||||
@ -2322,7 +2331,7 @@ int java_lang_invoke_AdapterMethodHandle::_conversion_offset;
|
||||
|
||||
void java_lang_invoke_MethodHandle::compute_offsets() {
|
||||
klassOop k = SystemDictionary::MethodHandle_klass();
|
||||
if (k != NULL && EnableMethodHandles) {
|
||||
if (k != NULL && EnableInvokeDynamic) {
|
||||
bool allow_super = false;
|
||||
if (AllowTransitionalJSR292) allow_super = true; // temporary, to access java.dyn.MethodHandleImpl
|
||||
compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature(), allow_super);
|
||||
@ -2337,7 +2346,7 @@ void java_lang_invoke_MethodHandle::compute_offsets() {
|
||||
|
||||
void java_lang_invoke_MemberName::compute_offsets() {
|
||||
klassOop k = SystemDictionary::MemberName_klass();
|
||||
if (k != NULL && EnableMethodHandles) {
|
||||
if (k != NULL && EnableInvokeDynamic) {
|
||||
compute_offset(_clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature());
|
||||
compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature());
|
||||
compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::object_signature());
|
||||
@ -2349,14 +2358,14 @@ void java_lang_invoke_MemberName::compute_offsets() {
|
||||
|
||||
void java_lang_invoke_DirectMethodHandle::compute_offsets() {
|
||||
klassOop k = SystemDictionary::DirectMethodHandle_klass();
|
||||
if (k != NULL && EnableMethodHandles) {
|
||||
if (k != NULL && EnableInvokeDynamic) {
|
||||
compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void java_lang_invoke_BoundMethodHandle::compute_offsets() {
|
||||
klassOop k = SystemDictionary::BoundMethodHandle_klass();
|
||||
if (k != NULL && EnableMethodHandles) {
|
||||
if (k != NULL && EnableInvokeDynamic) {
|
||||
compute_offset(_vmargslot_offset, k, vmSymbols::vmargslot_name(), vmSymbols::int_signature(), true);
|
||||
compute_offset(_argument_offset, k, vmSymbols::argument_name(), vmSymbols::object_signature(), true);
|
||||
}
|
||||
@ -2364,7 +2373,7 @@ void java_lang_invoke_BoundMethodHandle::compute_offsets() {
|
||||
|
||||
void java_lang_invoke_AdapterMethodHandle::compute_offsets() {
|
||||
klassOop k = SystemDictionary::AdapterMethodHandle_klass();
|
||||
if (k != NULL && EnableMethodHandles) {
|
||||
if (k != NULL && EnableInvokeDynamic) {
|
||||
compute_offset(_conversion_offset, k, vmSymbols::conversion_name(), vmSymbols::int_signature(), true);
|
||||
}
|
||||
}
|
||||
@ -2982,7 +2991,7 @@ void JavaClasses::compute_offsets() {
|
||||
java_lang_Class::compute_offsets();
|
||||
java_lang_Thread::compute_offsets();
|
||||
java_lang_ThreadGroup::compute_offsets();
|
||||
if (EnableMethodHandles) {
|
||||
if (EnableInvokeDynamic) {
|
||||
java_lang_invoke_MethodHandle::compute_offsets();
|
||||
java_lang_invoke_MemberName::compute_offsets();
|
||||
java_lang_invoke_DirectMethodHandle::compute_offsets();
|
||||
@ -2990,8 +2999,6 @@ void JavaClasses::compute_offsets() {
|
||||
java_lang_invoke_AdapterMethodHandle::compute_offsets();
|
||||
java_lang_invoke_MethodType::compute_offsets();
|
||||
java_lang_invoke_MethodTypeForm::compute_offsets();
|
||||
}
|
||||
if (EnableInvokeDynamic) {
|
||||
java_lang_invoke_CallSite::compute_offsets();
|
||||
}
|
||||
java_security_AccessControlContext::compute_offsets();
|
||||
|
@ -109,6 +109,30 @@ class java_lang_String : AllStatic {
|
||||
static char* as_platform_dependent_str(Handle java_string, TRAPS);
|
||||
static jchar* as_unicode_string(oop java_string, int& length);
|
||||
|
||||
// Compute the hash value for a java.lang.String object which would
|
||||
// contain the characters passed in. This hash value is used for at
|
||||
// least two purposes.
|
||||
//
|
||||
// (a) As the hash value used by the StringTable for bucket selection
|
||||
// and comparison (stored in the HashtableEntry structures). This
|
||||
// is used in the String.intern() method.
|
||||
//
|
||||
// (b) As the hash value used by the String object itself, in
|
||||
// String.hashCode(). This value is normally calculate in Java code
|
||||
// in the String.hashCode method(), but is precomputed for String
|
||||
// objects in the shared archive file.
|
||||
//
|
||||
// For this reason, THIS ALGORITHM MUST MATCH String.hashCode().
|
||||
static unsigned int hash_string(jchar* s, int len) {
|
||||
unsigned int h = 0;
|
||||
while (len-- > 0) {
|
||||
h = 31*h + (unsigned int) *s;
|
||||
s++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
static unsigned int hash_string(oop java_string);
|
||||
|
||||
static bool equals(oop java_string, jchar* chars, int len);
|
||||
|
||||
// Conversion between '.' and '/' formats
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -480,33 +480,6 @@ class StableMemoryChecker : public StackObj {
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Compute the hash value for a java.lang.String object which would
|
||||
// contain the characters passed in. This hash value is used for at
|
||||
// least two purposes.
|
||||
//
|
||||
// (a) As the hash value used by the StringTable for bucket selection
|
||||
// and comparison (stored in the HashtableEntry structures). This
|
||||
// is used in the String.intern() method.
|
||||
//
|
||||
// (b) As the hash value used by the String object itself, in
|
||||
// String.hashCode(). This value is normally calculate in Java code
|
||||
// in the String.hashCode method(), but is precomputed for String
|
||||
// objects in the shared archive file.
|
||||
//
|
||||
// For this reason, THIS ALGORITHM MUST MATCH String.hashCode().
|
||||
|
||||
int StringTable::hash_string(jchar* s, int len) {
|
||||
unsigned h = 0;
|
||||
while (len-- > 0) {
|
||||
h = 31*h + (unsigned) *s;
|
||||
s++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
StringTable* StringTable::_the_table = NULL;
|
||||
|
||||
oop StringTable::lookup(int index, jchar* name,
|
||||
@ -561,7 +534,7 @@ oop StringTable::lookup(Symbol* symbol) {
|
||||
ResourceMark rm;
|
||||
int length;
|
||||
jchar* chars = symbol->as_unicode(length);
|
||||
unsigned int hashValue = hash_string(chars, length);
|
||||
unsigned int hashValue = java_lang_String::hash_string(chars, length);
|
||||
int index = the_table()->hash_to_index(hashValue);
|
||||
return the_table()->lookup(index, chars, length, hashValue);
|
||||
}
|
||||
@ -569,7 +542,7 @@ oop StringTable::lookup(Symbol* symbol) {
|
||||
|
||||
oop StringTable::intern(Handle string_or_null, jchar* name,
|
||||
int len, TRAPS) {
|
||||
unsigned int hashValue = hash_string(name, len);
|
||||
unsigned int hashValue = java_lang_String::hash_string(name, len);
|
||||
int index = the_table()->hash_to_index(hashValue);
|
||||
oop string = the_table()->lookup(index, name, len, hashValue);
|
||||
|
||||
@ -663,10 +636,7 @@ void StringTable::verify() {
|
||||
oop s = p->literal();
|
||||
guarantee(s != NULL, "interned string is NULL");
|
||||
guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
|
||||
|
||||
int length;
|
||||
jchar* chars = java_lang_String::as_unicode_string(s, length);
|
||||
unsigned int h = hash_string(chars, length);
|
||||
unsigned int h = java_lang_String::hash_string(s);
|
||||
guarantee(p->hash() == h, "broken hash in string table entry");
|
||||
guarantee(the_table()->hash_to_index(h) == i,
|
||||
"wrong index in string table");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -242,8 +242,6 @@ public:
|
||||
_the_table = new StringTable(t, number_of_entries);
|
||||
}
|
||||
|
||||
static int hash_string(jchar* s, int len);
|
||||
|
||||
// GC support
|
||||
// Delete pointers to otherwise-unreachable objects.
|
||||
static void unlink(BoolObjectClosure* cl);
|
||||
|
@ -1017,7 +1017,7 @@ klassOop SystemDictionary::parse_stream(Symbol* class_name,
|
||||
}
|
||||
|
||||
if (host_klass.not_null() && k.not_null()) {
|
||||
assert(AnonymousClasses, "");
|
||||
assert(EnableInvokeDynamic, "");
|
||||
// If it's anonymous, initialize it now, since nobody else will.
|
||||
k->set_host_klass(host_klass());
|
||||
|
||||
@ -1940,7 +1940,7 @@ bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) {
|
||||
}
|
||||
Symbol* backup_symbol = NULL; // symbol to try if the current symbol fails
|
||||
if (init_opt == SystemDictionary::Pre_JSR292) {
|
||||
if (!EnableMethodHandles) try_load = false; // do not bother to load such classes
|
||||
if (!EnableInvokeDynamic) try_load = false; // do not bother to load such classes
|
||||
if (AllowTransitionalJSR292) {
|
||||
backup_symbol = find_backup_class_name(symbol);
|
||||
if (try_load && PreferTransitionalJSR292) {
|
||||
@ -2038,25 +2038,15 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
|
||||
instanceKlass::cast(WK_KLASS(FinalReference_klass))->set_reference_type(REF_FINAL);
|
||||
instanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM);
|
||||
|
||||
WKID meth_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
|
||||
WKID meth_group_end = WK_KLASS_ENUM_NAME(WrongMethodTypeException_klass);
|
||||
initialize_wk_klasses_until(meth_group_start, scan, CHECK);
|
||||
if (EnableMethodHandles) {
|
||||
initialize_wk_klasses_through(meth_group_end, scan, CHECK);
|
||||
}
|
||||
if (_well_known_klasses[meth_group_start] == NULL) {
|
||||
// Skip the rest of the method handle classes, if MethodHandle is not loaded.
|
||||
scan = WKID(meth_group_end+1);
|
||||
}
|
||||
WKID indy_group_start = WK_KLASS_ENUM_NAME(Linkage_klass);
|
||||
WKID indy_group_end = WK_KLASS_ENUM_NAME(CallSite_klass);
|
||||
initialize_wk_klasses_until(indy_group_start, scan, CHECK);
|
||||
// JSR 292 classes
|
||||
WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
|
||||
WKID jsr292_group_end = WK_KLASS_ENUM_NAME(CallSite_klass);
|
||||
initialize_wk_klasses_until(jsr292_group_start, scan, CHECK);
|
||||
if (EnableInvokeDynamic) {
|
||||
initialize_wk_klasses_through(indy_group_end, scan, CHECK);
|
||||
}
|
||||
if (_well_known_klasses[indy_group_start] == NULL) {
|
||||
// Skip the rest of the dynamic typing classes, if Linkage is not loaded.
|
||||
scan = WKID(indy_group_end+1);
|
||||
initialize_wk_klasses_through(jsr292_group_end, scan, CHECK);
|
||||
} else {
|
||||
// Skip the JSR 292 classes, if not enabled.
|
||||
scan = WKID(jsr292_group_end + 1);
|
||||
}
|
||||
|
||||
initialize_wk_klasses_until(WKID_LIMIT, scan, CHECK);
|
||||
@ -2407,7 +2397,7 @@ methodOop SystemDictionary::find_method_handle_invoke(Symbol* name,
|
||||
Symbol* signature,
|
||||
KlassHandle accessing_klass,
|
||||
TRAPS) {
|
||||
if (!EnableMethodHandles) return NULL;
|
||||
if (!EnableInvokeDynamic) return NULL;
|
||||
vmSymbols::SID name_id = vmSymbols::find_sid(name);
|
||||
assert(name_id != vmSymbols::NO_SID, "must be a known name");
|
||||
unsigned int hash = invoke_method_table()->compute_hash(signature, name_id);
|
||||
|
@ -207,7 +207,7 @@ class SystemDictionary : AllStatic {
|
||||
|
||||
enum InitOption {
|
||||
Pre, // preloaded; error if not present
|
||||
Pre_JSR292, // preloaded if EnableMethodHandles
|
||||
Pre_JSR292, // preloaded if EnableInvokeDynamic
|
||||
|
||||
// Order is significant. Options before this point require resolve_or_fail.
|
||||
// Options after this point will use resolve_or_null instead.
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "code/nmethod.hpp"
|
||||
#include "code/scopeDesc.hpp"
|
||||
#include "compiler/abstractCompiler.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/compileLog.hpp"
|
||||
#include "compiler/compilerOracle.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
@ -469,6 +470,7 @@ void nmethod::init_defaults() {
|
||||
|
||||
|
||||
nmethod* nmethod::new_native_nmethod(methodHandle method,
|
||||
int compile_id,
|
||||
CodeBuffer *code_buffer,
|
||||
int vep_offset,
|
||||
int frame_complete,
|
||||
@ -485,7 +487,7 @@ nmethod* nmethod::new_native_nmethod(methodHandle method,
|
||||
offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
|
||||
offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
|
||||
nm = new (native_nmethod_size)
|
||||
nmethod(method(), native_nmethod_size, &offsets,
|
||||
nmethod(method(), native_nmethod_size, compile_id, &offsets,
|
||||
code_buffer, frame_size,
|
||||
basic_lock_owner_sp_offset, basic_lock_sp_offset,
|
||||
oop_maps);
|
||||
@ -610,6 +612,7 @@ nmethod* nmethod::new_nmethod(methodHandle method,
|
||||
nmethod::nmethod(
|
||||
methodOop method,
|
||||
int nmethod_size,
|
||||
int compile_id,
|
||||
CodeOffsets* offsets,
|
||||
CodeBuffer* code_buffer,
|
||||
int frame_size,
|
||||
@ -644,7 +647,7 @@ nmethod::nmethod(
|
||||
_handler_table_offset = _dependencies_offset;
|
||||
_nul_chk_table_offset = _handler_table_offset;
|
||||
_nmethod_end_offset = _nul_chk_table_offset;
|
||||
_compile_id = 0; // default
|
||||
_compile_id = compile_id;
|
||||
_comp_level = CompLevel_none;
|
||||
_entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
|
||||
_verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry);
|
||||
@ -930,72 +933,11 @@ void nmethod::log_new_nmethod() const {
|
||||
#undef LOG_OFFSET
|
||||
|
||||
|
||||
void nmethod::print_compilation(outputStream *st, const char *method_name, const char *title,
|
||||
methodOop method, bool is_blocking, int compile_id, int bci, int comp_level) {
|
||||
bool is_synchronized = false, has_xhandler = false, is_native = false;
|
||||
int code_size = -1;
|
||||
if (method != NULL) {
|
||||
is_synchronized = method->is_synchronized();
|
||||
has_xhandler = method->has_exception_handler();
|
||||
is_native = method->is_native();
|
||||
code_size = method->code_size();
|
||||
}
|
||||
// print compilation number
|
||||
st->print("%7d %3d", (int)tty->time_stamp().milliseconds(), compile_id);
|
||||
|
||||
// print method attributes
|
||||
const bool is_osr = bci != InvocationEntryBci;
|
||||
const char blocking_char = is_blocking ? 'b' : ' ';
|
||||
const char compile_type = is_osr ? '%' : ' ';
|
||||
const char sync_char = is_synchronized ? 's' : ' ';
|
||||
const char exception_char = has_xhandler ? '!' : ' ';
|
||||
const char native_char = is_native ? 'n' : ' ';
|
||||
st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char);
|
||||
if (TieredCompilation) {
|
||||
st->print("%d ", comp_level);
|
||||
}
|
||||
|
||||
// print optional title
|
||||
bool do_nl = false;
|
||||
if (title != NULL) {
|
||||
int tlen = (int) strlen(title);
|
||||
bool do_nl = false;
|
||||
if (tlen > 0 && title[tlen-1] == '\n') { tlen--; do_nl = true; }
|
||||
st->print("%.*s", tlen, title);
|
||||
} else {
|
||||
do_nl = true;
|
||||
}
|
||||
|
||||
// print method name string if given
|
||||
if (method_name != NULL) {
|
||||
st->print(method_name);
|
||||
} else {
|
||||
// otherwise as the method to print itself
|
||||
if (method != NULL && !Universe::heap()->is_gc_active()) {
|
||||
method->print_short_name(st);
|
||||
} else {
|
||||
st->print("(method)");
|
||||
}
|
||||
}
|
||||
|
||||
if (method != NULL) {
|
||||
// print osr_bci if any
|
||||
if (is_osr) st->print(" @ %d", bci);
|
||||
// print method size
|
||||
st->print(" (%d bytes)", code_size);
|
||||
}
|
||||
if (do_nl) st->cr();
|
||||
}
|
||||
|
||||
// Print out more verbose output usually for a newly created nmethod.
|
||||
void nmethod::print_on(outputStream* st, const char* title) const {
|
||||
void nmethod::print_on(outputStream* st, const char* msg) const {
|
||||
if (st != NULL) {
|
||||
ttyLocker ttyl;
|
||||
print_compilation(st, /*method_name*/NULL, title,
|
||||
method(), /*is_blocking*/false,
|
||||
compile_id(),
|
||||
is_osr_method() ? osr_entry_bci() : InvocationEntryBci,
|
||||
comp_level());
|
||||
CompileTask::print_compilation(st, this, msg);
|
||||
if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this);
|
||||
}
|
||||
}
|
||||
@ -1309,8 +1251,7 @@ void nmethod::log_state_change() const {
|
||||
}
|
||||
}
|
||||
if (PrintCompilation && _state != unloaded) {
|
||||
print_on(tty, _state == zombie ? "made zombie " : "made not entrant ");
|
||||
tty->cr();
|
||||
print_on(tty, _state == zombie ? "made zombie" : "made not entrant");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1816,7 +1757,7 @@ bool nmethod::test_set_oops_do_mark() {
|
||||
break;
|
||||
}
|
||||
// Mark was clear when we first saw this guy.
|
||||
NOT_PRODUCT(if (TraceScavenge) print_on(tty, "oops_do, mark\n"));
|
||||
NOT_PRODUCT(if (TraceScavenge) print_on(tty, "oops_do, mark"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1841,7 +1782,7 @@ void nmethod::oops_do_marking_epilogue() {
|
||||
nmethod* next = cur->_oops_do_mark_link;
|
||||
cur->_oops_do_mark_link = NULL;
|
||||
cur->fix_oop_relocations();
|
||||
NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark\n"));
|
||||
NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark"));
|
||||
cur = next;
|
||||
}
|
||||
void* required = _oops_do_mark_nmethods;
|
||||
@ -2396,7 +2337,7 @@ void nmethod::print() const {
|
||||
ResourceMark rm;
|
||||
ttyLocker ttyl; // keep the following output all in one block
|
||||
|
||||
tty->print("Compiled ");
|
||||
tty->print("Compiled method ");
|
||||
|
||||
if (is_compiled_by_c1()) {
|
||||
tty->print("(c1) ");
|
||||
@ -2408,8 +2349,8 @@ void nmethod::print() const {
|
||||
tty->print("(nm) ");
|
||||
}
|
||||
|
||||
print_on(tty, "nmethod");
|
||||
tty->cr();
|
||||
print_on(tty, NULL);
|
||||
|
||||
if (WizardMode) {
|
||||
tty->print("((nmethod*) "INTPTR_FORMAT ") ", this);
|
||||
tty->print(" for method " INTPTR_FORMAT , (address)method());
|
||||
@ -2796,7 +2737,8 @@ void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin,
|
||||
#ifndef PRODUCT
|
||||
|
||||
void nmethod::print_value_on(outputStream* st) const {
|
||||
print_on(st, "nmethod");
|
||||
st->print("nmethod");
|
||||
print_on(st, NULL);
|
||||
}
|
||||
|
||||
void nmethod::print_calls(outputStream* st) {
|
||||
|
@ -229,6 +229,7 @@ class nmethod : public CodeBlob {
|
||||
// For native wrappers
|
||||
nmethod(methodOop method,
|
||||
int nmethod_size,
|
||||
int compile_id,
|
||||
CodeOffsets* offsets,
|
||||
CodeBuffer *code_buffer,
|
||||
int frame_size,
|
||||
@ -299,6 +300,7 @@ class nmethod : public CodeBlob {
|
||||
int comp_level);
|
||||
|
||||
static nmethod* new_native_nmethod(methodHandle method,
|
||||
int compile_id,
|
||||
CodeBuffer *code_buffer,
|
||||
int vep_offset,
|
||||
int frame_complete,
|
||||
@ -500,8 +502,8 @@ public:
|
||||
address continuation_for_implicit_exception(address pc);
|
||||
|
||||
// On-stack replacement support
|
||||
int osr_entry_bci() const { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _entry_bci; }
|
||||
address osr_entry() const { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); return _osr_entry_point; }
|
||||
int osr_entry_bci() const { assert(is_osr_method(), "wrong kind of nmethod"); return _entry_bci; }
|
||||
address osr_entry() const { assert(is_osr_method(), "wrong kind of nmethod"); return _osr_entry_point; }
|
||||
void invalidate_osr_method();
|
||||
nmethod* osr_link() const { return _osr_link; }
|
||||
void set_osr_link(nmethod *n) { _osr_link = n; }
|
||||
@ -608,10 +610,6 @@ public:
|
||||
void verify_scopes();
|
||||
void verify_interrupt_point(address interrupt_point);
|
||||
|
||||
// print compilation helper
|
||||
static void print_compilation(outputStream *st, const char *method_name, const char *title,
|
||||
methodOop method, bool is_blocking, int compile_id, int bci, int comp_level);
|
||||
|
||||
// printing support
|
||||
void print() const;
|
||||
void print_code();
|
||||
@ -627,7 +625,7 @@ public:
|
||||
|
||||
// need to re-define this from CodeBlob else the overload hides it
|
||||
virtual void print_on(outputStream* st) const { CodeBlob::print_on(st); }
|
||||
void print_on(outputStream* st, const char* title) const;
|
||||
void print_on(outputStream* st, const char* msg) const;
|
||||
|
||||
// Logging
|
||||
void log_identity(xmlStream* log) const;
|
||||
|
@ -268,11 +268,6 @@ void CompileTask::print() {
|
||||
}
|
||||
|
||||
|
||||
void CompileTask::print_compilation(outputStream *st, methodOop method, char* method_name) {
|
||||
nmethod::print_compilation(st, method_name,/*title*/ NULL, method,
|
||||
is_blocking(), compile_id(), osr_bci(), comp_level());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileTask::print_line_on_error
|
||||
//
|
||||
@ -284,32 +279,116 @@ void CompileTask::print_compilation(outputStream *st, methodOop method, char* me
|
||||
// Otherwise it's the same as CompileTask::print_line()
|
||||
//
|
||||
void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) {
|
||||
methodOop method = (methodOop)JNIHandles::resolve(_method);
|
||||
// print compiler name
|
||||
st->print("%s:", CompileBroker::compiler(comp_level())->name());
|
||||
char* method_name = NULL;
|
||||
if (method != NULL) {
|
||||
method_name = method->name_and_sig_as_C_string(buf, buflen);
|
||||
}
|
||||
print_compilation(st, method, method_name);
|
||||
print_compilation(st);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileTask::print_line
|
||||
void CompileTask::print_line() {
|
||||
Thread *thread = Thread::current();
|
||||
methodHandle method(thread,
|
||||
(methodOop)JNIHandles::resolve(method_handle()));
|
||||
ResourceMark rm(thread);
|
||||
|
||||
ttyLocker ttyl; // keep the following output all in one block
|
||||
|
||||
// print compiler name if requested
|
||||
if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler(comp_level())->name());
|
||||
print_compilation(tty, method(), NULL);
|
||||
print_compilation();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileTask::print_compilation_impl
|
||||
void CompileTask::print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, bool is_osr_method, int osr_bci, bool is_blocking, const char* msg) {
|
||||
st->print("%7d ", (int) st->time_stamp().milliseconds()); // print timestamp
|
||||
st->print("%4d ", compile_id); // print compilation number
|
||||
|
||||
// method attributes
|
||||
const char compile_type = is_osr_method ? '%' : ' ';
|
||||
const char sync_char = method->is_synchronized() ? 's' : ' ';
|
||||
const char exception_char = method->has_exception_handler() ? '!' : ' ';
|
||||
const char blocking_char = is_blocking ? 'b' : ' ';
|
||||
const char native_char = method->is_native() ? 'n' : ' ';
|
||||
|
||||
// print method attributes
|
||||
st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char);
|
||||
|
||||
if (TieredCompilation) {
|
||||
if (comp_level != -1) st->print("%d ", comp_level);
|
||||
else st->print("- ");
|
||||
}
|
||||
st->print(" "); // more indent
|
||||
|
||||
method->print_short_name(st);
|
||||
if (is_osr_method) {
|
||||
st->print(" @ %d", osr_bci);
|
||||
}
|
||||
st->print(" (%d bytes)", method->code_size());
|
||||
|
||||
if (msg != NULL) {
|
||||
st->print(" %s", msg);
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileTask::print_inlining
|
||||
void CompileTask::print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg) {
|
||||
// 1234567
|
||||
st->print(" "); // print timestamp
|
||||
// 1234
|
||||
st->print(" "); // print compilation number
|
||||
|
||||
// method attributes
|
||||
const char sync_char = method->is_synchronized() ? 's' : ' ';
|
||||
const char exception_char = method->has_exception_handlers() ? '!' : ' ';
|
||||
const char monitors_char = method->has_monitor_bytecodes() ? 'm' : ' ';
|
||||
|
||||
// print method attributes
|
||||
st->print(" %c%c%c ", sync_char, exception_char, monitors_char);
|
||||
|
||||
if (TieredCompilation) {
|
||||
st->print(" ");
|
||||
}
|
||||
st->print(" "); // more indent
|
||||
st->print(" "); // initial inlining indent
|
||||
|
||||
for (int i = 0; i < inline_level; i++) st->print(" ");
|
||||
|
||||
st->print("@ %d ", bci); // print bci
|
||||
method->print_short_name(st);
|
||||
st->print(" (%d bytes)", method->code_size());
|
||||
|
||||
if (msg != NULL) {
|
||||
st->print(" %s", msg);
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileTask::print_inline_indent
|
||||
void CompileTask::print_inline_indent(int inline_level, outputStream* st) {
|
||||
// 1234567
|
||||
st->print(" "); // print timestamp
|
||||
// 1234
|
||||
st->print(" "); // print compilation number
|
||||
// %s!bn
|
||||
st->print(" "); // print method attributes
|
||||
if (TieredCompilation) {
|
||||
st->print(" ");
|
||||
}
|
||||
st->print(" "); // more indent
|
||||
st->print(" "); // initial inlining indent
|
||||
for (int i = 0; i < inline_level; i++) st->print(" ");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileTask::print_compilation
|
||||
void CompileTask::print_compilation(outputStream* st) {
|
||||
oop rem = JNIHandles::resolve(method_handle());
|
||||
assert(rem != NULL && rem->is_method(), "must be");
|
||||
methodOop method = (methodOop) rem;
|
||||
bool is_osr_method = osr_bci() != InvocationEntryBci;
|
||||
print_compilation_impl(st, method, compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileTask::log_task
|
||||
void CompileTask::log_task(xmlStream* log) {
|
||||
@ -874,6 +953,14 @@ void CompileBroker::compile_method_base(methodHandle method,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (osr_bci != -1 && !FLAG_IS_DEFAULT(OSROnlyBCI)) {
|
||||
if ((OSROnlyBCI > 0) ? (OSROnlyBCI != osr_bci) : (-OSROnlyBCI == osr_bci)) {
|
||||
// Positive OSROnlyBCI means only compile that bci. Negative means don't compile that BCI.
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If this method is already in the compile queue, then
|
||||
// we do not block the current thread.
|
||||
@ -1078,7 +1165,13 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
|
||||
// do the compilation
|
||||
if (method->is_native()) {
|
||||
if (!PreferInterpreterNativeStubs) {
|
||||
(void) AdapterHandlerLibrary::create_native_wrapper(method);
|
||||
// Acquire our lock.
|
||||
int compile_id;
|
||||
{
|
||||
MutexLocker locker(MethodCompileQueue_lock, THREAD);
|
||||
compile_id = assign_compile_id(method, standard_entry_bci);
|
||||
}
|
||||
(void) AdapterHandlerLibrary::create_native_wrapper(method, compile_id);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -1186,7 +1279,6 @@ uint CompileBroker::assign_compile_id(methodHandle method, int osr_bci) {
|
||||
assert(MethodCompileQueue_lock->owner() == Thread::current(),
|
||||
"must hold the compilation queue lock");
|
||||
bool is_osr = (osr_bci != standard_entry_bci);
|
||||
assert(!method->is_native(), "no longer compile natives");
|
||||
uint id;
|
||||
if (CICountOSR && is_osr) {
|
||||
id = ++_osr_compilation_id;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -56,7 +56,6 @@ class CompileTask : public CHeapObj {
|
||||
int _hot_count; // information about its invocation counter
|
||||
const char* _comment; // more info about the task
|
||||
|
||||
void print_compilation(outputStream *st, methodOop method, char* method_name);
|
||||
public:
|
||||
CompileTask() {
|
||||
_lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock");
|
||||
@ -96,10 +95,26 @@ class CompileTask : public CHeapObj {
|
||||
CompileTask* prev() const { return _prev; }
|
||||
void set_prev(CompileTask* prev) { _prev = prev; }
|
||||
|
||||
private:
|
||||
static void print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false, const char* msg = NULL);
|
||||
|
||||
public:
|
||||
void print_compilation(outputStream* st = tty);
|
||||
static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL) {
|
||||
print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(), nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false, msg);
|
||||
}
|
||||
|
||||
static void print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);
|
||||
static void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
|
||||
print_inlining(tty, method, inline_level, bci, msg);
|
||||
}
|
||||
|
||||
static void print_inline_indent(int inline_level, outputStream* st = tty);
|
||||
|
||||
void print();
|
||||
void print_line();
|
||||
|
||||
void print_line_on_error(outputStream* st, char* buf, int buflen);
|
||||
|
||||
void log_task(xmlStream* log);
|
||||
void log_task_queued();
|
||||
void log_task_start(CompileLog* log);
|
||||
|
@ -2383,17 +2383,6 @@ run:
|
||||
}
|
||||
|
||||
DEFAULT:
|
||||
#ifdef ZERO
|
||||
// Some zero configurations use the C++ interpreter as a
|
||||
// fallback interpreter and have support for platform
|
||||
// specific fast bytecodes which aren't supported here, so
|
||||
// redispatch to the equivalent non-fast bytecode when they
|
||||
// are encountered.
|
||||
if (Bytecodes::is_defined((Bytecodes::Code)opcode)) {
|
||||
opcode = (jubyte)Bytecodes::java_code((Bytecodes::Code)opcode);
|
||||
goto opcode_switch;
|
||||
}
|
||||
#endif
|
||||
fatal(err_msg("Unimplemented opcode %d = %s", opcode,
|
||||
Bytecodes::name((Bytecodes::Code)opcode)));
|
||||
goto finish;
|
||||
|
@ -176,7 +176,7 @@ void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHand
|
||||
|
||||
void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
|
||||
methodOop result_oop = klass->uncached_lookup_method(name, signature);
|
||||
if (EnableMethodHandles && result_oop != NULL) {
|
||||
if (EnableInvokeDynamic && result_oop != NULL) {
|
||||
switch (result_oop->intrinsic_id()) {
|
||||
case vmIntrinsics::_invokeExact:
|
||||
case vmIntrinsics::_invokeGeneric:
|
||||
@ -214,7 +214,7 @@ void LinkResolver::lookup_implicit_method(methodHandle& result,
|
||||
KlassHandle klass, Symbol* name, Symbol* signature,
|
||||
KlassHandle current_klass,
|
||||
TRAPS) {
|
||||
if (EnableMethodHandles &&
|
||||
if (EnableInvokeDynamic &&
|
||||
klass() == SystemDictionary::MethodHandle_klass() &&
|
||||
methodOopDesc::is_method_handle_invoke_name(name)) {
|
||||
if (!THREAD->is_Compiler_thread() && !MethodHandles::enabled()) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -80,16 +80,7 @@ public:
|
||||
oop obj = *p;
|
||||
if (obj->klass() == SystemDictionary::String_klass()) {
|
||||
|
||||
int hash;
|
||||
typeArrayOop value = java_lang_String::value(obj);
|
||||
int length = java_lang_String::length(obj);
|
||||
if (length == 0) {
|
||||
hash = 0;
|
||||
} else {
|
||||
int offset = java_lang_String::offset(obj);
|
||||
jchar* s = value->char_at_addr(offset);
|
||||
hash = StringTable::hash_string(s, length);
|
||||
}
|
||||
int hash = java_lang_String::hash_string(obj);
|
||||
obj->int_field_put(hash_offset, hash);
|
||||
}
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
|
||||
assert(obj->is_constantPool(), "should be constant pool");
|
||||
constantPoolOop cp = (constantPoolOop) obj;
|
||||
if (cp->tags() != NULL &&
|
||||
(!JavaObjectsInPerm || (AnonymousClasses && cp->has_pseudo_string()))) {
|
||||
(!JavaObjectsInPerm || (EnableInvokeDynamic && cp->has_pseudo_string()))) {
|
||||
for (int i = 1; i < cp->length(); ++i) {
|
||||
if (cp->tag_at(i).is_string()) {
|
||||
oop* base = cp->obj_at_addr_raw(i);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -429,7 +429,7 @@ class constantPoolOopDesc : public oopDesc {
|
||||
|
||||
// A "pseudo-string" is an non-string oop that has found is way into
|
||||
// a String entry.
|
||||
// Under AnonymousClasses this can happen if the user patches a live
|
||||
// Under EnableInvokeDynamic this can happen if the user patches a live
|
||||
// object into a CONSTANT_String entry of an anonymous class.
|
||||
// Method oops internally created for method handles may also
|
||||
// use pseudo-strings to link themselves to related metaobjects.
|
||||
@ -442,7 +442,7 @@ class constantPoolOopDesc : public oopDesc {
|
||||
}
|
||||
|
||||
void pseudo_string_at_put(int which, oop x) {
|
||||
assert(AnonymousClasses, "");
|
||||
assert(EnableInvokeDynamic, "");
|
||||
set_pseudo_string(); // mark header
|
||||
assert(tag_at(which).is_string() || tag_at(which).is_unresolved_string(), "Corrupted constant pool");
|
||||
string_at_put(which, x); // this works just fine
|
||||
|
@ -2337,7 +2337,7 @@ void instanceKlass::oop_print_on(oop obj, outputStream* st) {
|
||||
st->print_cr(BULLET"fake entry for oop_size: %d", java_lang_Class::oop_size(obj));
|
||||
st->print_cr(BULLET"fake entry for static_oop_field_count: %d", java_lang_Class::static_oop_field_count(obj));
|
||||
klassOop real_klass = java_lang_Class::as_klassOop(obj);
|
||||
if (real_klass && real_klass->klass_part()->oop_is_instance()) {
|
||||
if (real_klass != NULL && real_klass->klass_part()->oop_is_instance()) {
|
||||
instanceKlass::cast(real_klass)->do_local_static_fields(&print_field);
|
||||
}
|
||||
} else if (as_klassOop() == SystemDictionary::MethodType_klass()) {
|
||||
|
@ -182,7 +182,7 @@ class instanceKlass: public Klass {
|
||||
// Protection domain.
|
||||
oop _protection_domain;
|
||||
// Host class, which grants its access privileges to this class also.
|
||||
// This is only non-null for an anonymous class (AnonymousClasses enabled).
|
||||
// This is only non-null for an anonymous class (JSR 292 enabled).
|
||||
// The host class is either named, or a previously loaded anonymous class.
|
||||
klassOop _host_klass;
|
||||
// Class signers.
|
||||
|
@ -36,6 +36,8 @@
|
||||
|
||||
|
||||
class instanceMirrorKlass: public instanceKlass {
|
||||
friend class VMStructs;
|
||||
|
||||
private:
|
||||
static int _offset_of_static_fields;
|
||||
|
||||
|
@ -500,7 +500,7 @@ const char* Klass::external_name() const {
|
||||
if (oop_is_instance()) {
|
||||
instanceKlass* ik = (instanceKlass*) this;
|
||||
if (ik->is_anonymous()) {
|
||||
assert(AnonymousClasses, "");
|
||||
assert(EnableInvokeDynamic, "");
|
||||
intptr_t hash = ik->java_mirror()->identity_hash();
|
||||
char hash_buf[40];
|
||||
sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
|
||||
|
@ -607,7 +607,7 @@ class methodOopDesc : public oopDesc {
|
||||
// method handles want to be able to push a few extra values (e.g., a bound receiver), and
|
||||
// invokedynamic sometimes needs to push a bootstrap method, call site, and arglist,
|
||||
// all without checking for a stack overflow
|
||||
static int extra_stack_entries() { return (EnableMethodHandles ? (int)MethodHandlePushLimit : 0) + (EnableInvokeDynamic ? 3 : 0); }
|
||||
static int extra_stack_entries() { return EnableInvokeDynamic ? (int) MethodHandlePushLimit + 3 : 0; }
|
||||
static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize()
|
||||
|
||||
// RedefineClasses() support:
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/compileLog.hpp"
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
@ -75,13 +76,6 @@ InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvm
|
||||
assert(!UseOldInlining, "do not use for old stuff");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void print_indent(int depth) {
|
||||
tty->print(" ");
|
||||
for (int i = depth; i != 0; --i) tty->print(" ");
|
||||
}
|
||||
|
||||
static bool is_init_with_ea(ciMethod* callee_method,
|
||||
ciMethod* caller_method, Compile* C) {
|
||||
// True when EA is ON and a java constructor is called or
|
||||
@ -100,7 +94,7 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_m
|
||||
if(callee_method->should_inline()) {
|
||||
*wci_result = *(WarmCallInfo::always_hot());
|
||||
if (PrintInlining && Verbose) {
|
||||
print_indent(inline_depth());
|
||||
CompileTask::print_inline_indent(inline_depth());
|
||||
tty->print_cr("Inlined method is hot: ");
|
||||
}
|
||||
return NULL;
|
||||
@ -116,7 +110,7 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_m
|
||||
size < InlineThrowMaxSize ) {
|
||||
wci_result->set_profit(wci_result->profit() * 100);
|
||||
if (PrintInlining && Verbose) {
|
||||
print_indent(inline_depth());
|
||||
CompileTask::print_inline_indent(inline_depth());
|
||||
tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
|
||||
}
|
||||
return NULL;
|
||||
@ -138,9 +132,9 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_m
|
||||
|
||||
max_size = C->freq_inline_size();
|
||||
if (size <= max_size && TraceFrequencyInlining) {
|
||||
print_indent(inline_depth());
|
||||
CompileTask::print_inline_indent(inline_depth());
|
||||
tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count);
|
||||
print_indent(inline_depth());
|
||||
CompileTask::print_inline_indent(inline_depth());
|
||||
callee_method->print();
|
||||
tty->cr();
|
||||
}
|
||||
@ -315,8 +309,25 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_
|
||||
if( inline_depth() > MaxInlineLevel ) {
|
||||
return "inlining too deep";
|
||||
}
|
||||
if( method() == callee_method &&
|
||||
inline_depth() > MaxRecursiveInlineLevel ) {
|
||||
|
||||
// We need to detect recursive inlining of method handle targets: if
|
||||
// the current method is a method handle adapter and one of the
|
||||
// callers is the same method as the callee, we bail out if
|
||||
// MaxRecursiveInlineLevel is hit.
|
||||
if (method()->is_method_handle_adapter()) {
|
||||
JVMState* jvms = caller_jvms();
|
||||
int inline_level = 0;
|
||||
while (jvms != NULL && jvms->has_method()) {
|
||||
if (jvms->method() == callee_method) {
|
||||
inline_level++;
|
||||
if (inline_level > MaxRecursiveInlineLevel)
|
||||
return "recursively inlining too deep";
|
||||
}
|
||||
jvms = jvms->caller();
|
||||
}
|
||||
}
|
||||
|
||||
if (method() == callee_method && inline_depth() > MaxRecursiveInlineLevel) {
|
||||
return "recursively inlining too deep";
|
||||
}
|
||||
|
||||
@ -368,18 +379,14 @@ bool pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* call
|
||||
#ifndef PRODUCT
|
||||
//------------------------------print_inlining---------------------------------
|
||||
// Really, the failure_msg can be a success message also.
|
||||
void InlineTree::print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const {
|
||||
print_indent(inline_depth());
|
||||
tty->print("@ %d ", caller_bci);
|
||||
if( callee_method ) callee_method->print_short_name();
|
||||
else tty->print(" callee not monotonic or profiled");
|
||||
tty->print(" %s", (failure_msg ? failure_msg : "inline"));
|
||||
if( Verbose && callee_method ) {
|
||||
void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const {
|
||||
CompileTask::print_inlining(callee_method, inline_depth(), caller_bci, failure_msg ? failure_msg : "inline");
|
||||
if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
|
||||
if (Verbose && callee_method) {
|
||||
const InlineTree *top = this;
|
||||
while( top->caller_tree() != NULL ) { top = top->caller_tree(); }
|
||||
tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
|
||||
}
|
||||
tty->cr();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -673,7 +673,7 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
|
||||
case Op_RegD:
|
||||
lrg.set_num_regs(2);
|
||||
// Define platform specific register pressure
|
||||
#ifdef SPARC
|
||||
#if defined(SPARC) || defined(ARM)
|
||||
lrg.set_reg_pressure(2);
|
||||
#elif defined(IA32)
|
||||
if( ireg == Op_RegL ) {
|
||||
|
@ -2544,6 +2544,36 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
|
||||
frc.inc_inner_loop_count();
|
||||
}
|
||||
break;
|
||||
case Op_LShiftI:
|
||||
case Op_RShiftI:
|
||||
case Op_URShiftI:
|
||||
case Op_LShiftL:
|
||||
case Op_RShiftL:
|
||||
case Op_URShiftL:
|
||||
if (Matcher::need_masked_shift_count) {
|
||||
// The cpu's shift instructions don't restrict the count to the
|
||||
// lower 5/6 bits. We need to do the masking ourselves.
|
||||
Node* in2 = n->in(2);
|
||||
juint mask = (n->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
|
||||
const TypeInt* t = in2->find_int_type();
|
||||
if (t != NULL && t->is_con()) {
|
||||
juint shift = t->get_con();
|
||||
if (shift > mask) { // Unsigned cmp
|
||||
Compile* C = Compile::current();
|
||||
n->set_req(2, ConNode::make(C, TypeInt::make(shift & mask)));
|
||||
}
|
||||
} else {
|
||||
if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) {
|
||||
Compile* C = Compile::current();
|
||||
Node* shift = new (C, 3) AndINode(in2, ConNode::make(C, TypeInt::make(mask)));
|
||||
n->set_req(2, shift);
|
||||
}
|
||||
}
|
||||
if (in2->outcnt() == 0) { // Remove dead node
|
||||
in2->disconnect_inputs(NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert( !n->is_Call(), "" );
|
||||
assert( !n->is_Mem(), "" );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@
|
||||
#include "ci/ciCallSite.hpp"
|
||||
#include "ci/ciMethodHandle.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/compileLog.hpp"
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "opto/addnode.hpp"
|
||||
@ -43,17 +44,17 @@
|
||||
#ifndef PRODUCT
|
||||
void trace_type_profile(ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
|
||||
if (TraceTypeProfile || PrintInlining || PrintOptoInlining) {
|
||||
tty->print(" ");
|
||||
for( int i = 0; i < depth; i++ ) tty->print(" ");
|
||||
if (!PrintOpto) {
|
||||
method->print_short_name();
|
||||
tty->print(" ->");
|
||||
if (!PrintInlining) {
|
||||
if (!PrintOpto && !PrintCompilation) {
|
||||
method->print_short_name();
|
||||
tty->cr();
|
||||
}
|
||||
CompileTask::print_inlining(prof_method, depth, bci);
|
||||
}
|
||||
tty->print(" @ %d ", bci);
|
||||
prof_method->print_short_name();
|
||||
tty->print(" >>TypeProfile (%d/%d counts) = ", receiver_count, site_count);
|
||||
CompileTask::print_inline_indent(depth);
|
||||
tty->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count);
|
||||
prof_klass->name()->print_symbol();
|
||||
tty->print_cr(" (%d bytes)", prof_method->code_size());
|
||||
tty->cr();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -269,13 +270,13 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
|
||||
}
|
||||
if (miss_cg != NULL) {
|
||||
if (next_hit_cg != NULL) {
|
||||
NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth(), jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)));
|
||||
NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)));
|
||||
// We don't need to record dependency on a receiver here and below.
|
||||
// Whenever we inline, the dependency is added by Parse::Parse().
|
||||
miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX);
|
||||
}
|
||||
if (miss_cg != NULL) {
|
||||
NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth(), jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count));
|
||||
NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count));
|
||||
cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0));
|
||||
if (cg != NULL) return cg;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -599,11 +599,35 @@ void IdealGraphPrinter::visit_node(Node *n, void *param) {
|
||||
|
||||
if (caller != NULL) {
|
||||
stringStream bciStream;
|
||||
ciMethod* last = NULL;
|
||||
int last_bci;
|
||||
while(caller) {
|
||||
if (caller->has_method()) {
|
||||
last = caller->method();
|
||||
last_bci = caller->bci();
|
||||
}
|
||||
bciStream.print("%d ", caller->bci());
|
||||
caller = caller->caller();
|
||||
}
|
||||
print_prop("bci", bciStream.as_string());
|
||||
if (last != NULL && last->has_linenumber_table() && last_bci >= 0) {
|
||||
print_prop("line", last->line_number_from_bci(last_bci));
|
||||
}
|
||||
}
|
||||
|
||||
if (node->debug_orig() != NULL) {
|
||||
stringStream dorigStream;
|
||||
Node* dorig = node->debug_orig();
|
||||
if (dorig) {
|
||||
dorigStream.print("%d ", dorig->_idx);
|
||||
Node* first = dorig;
|
||||
dorig = first->debug_orig();
|
||||
while (dorig && dorig != first) {
|
||||
dorigStream.print("%d ", dorig->_idx);
|
||||
dorig = dorig->debug_orig();
|
||||
}
|
||||
}
|
||||
print_prop("debug_orig", dorigStream.as_string());
|
||||
}
|
||||
|
||||
if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
|
||||
@ -628,6 +652,17 @@ void IdealGraphPrinter::walk_nodes(Node *start, void *param) {
|
||||
GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL);
|
||||
nodeStack.push(start);
|
||||
visited.test_set(start->_idx);
|
||||
if (C->cfg() != NULL) {
|
||||
// once we have a CFG there are some nodes that aren't really
|
||||
// reachable but are in the CFG so add them here.
|
||||
for (uint i = 0; i < C->cfg()->_blocks.size(); i++) {
|
||||
Block *b = C->cfg()->_blocks[i];
|
||||
for (uint s = 0; s < b->_nodes.size(); s++) {
|
||||
nodeStack.push(b->_nodes[s]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(nodeStack.length() > 0) {
|
||||
|
||||
Node *n = nodeStack.pop();
|
||||
@ -686,16 +721,23 @@ void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, in
|
||||
end_head();
|
||||
|
||||
head(SUCCESSORS_ELEMENT);
|
||||
for (uint s = 0; s < C->cfg()->_blocks[i]->_num_succs; s++) {
|
||||
for (uint s = 0; s < b->_num_succs; s++) {
|
||||
begin_elem(SUCCESSOR_ELEMENT);
|
||||
print_attr(BLOCK_NAME_PROPERTY, b->_succs[s]->_pre_order);
|
||||
end_elem();
|
||||
}
|
||||
tail(SUCCESSORS_ELEMENT);
|
||||
|
||||
head(NODES_ELEMENT);
|
||||
for (uint s = 0; s < b->_nodes.size(); s++) {
|
||||
begin_elem(NODE_ELEMENT);
|
||||
print_attr(NODE_ID_PROPERTY, get_node_id(b->_nodes[s]));
|
||||
end_elem();
|
||||
}
|
||||
tail(NODES_ELEMENT);
|
||||
|
||||
tail(BLOCK_ELEMENT);
|
||||
}
|
||||
|
||||
tail(CONTROL_FLOW_ELEMENT);
|
||||
}
|
||||
tail(GRAPH_ELEMENT);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,15 +43,6 @@ class ciMethod;
|
||||
|
||||
class IdealGraphPrinter
|
||||
{
|
||||
private:
|
||||
|
||||
enum State
|
||||
{
|
||||
Invalid,
|
||||
Valid,
|
||||
New
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static const char *INDENT;
|
||||
|
@ -42,6 +42,9 @@
|
||||
#ifdef TARGET_ARCH_MODEL_zero
|
||||
# include "adfiles/ad_zero.hpp"
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_MODEL_arm
|
||||
# include "adfiles/ad_arm.hpp"
|
||||
#endif
|
||||
|
||||
// Optimization - Graph Style
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/compileLog.hpp"
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "opto/addnode.hpp"
|
||||
@ -388,11 +389,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
|
||||
#endif
|
||||
if (kit.try_to_inline()) {
|
||||
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
|
||||
tty->print("Inlining intrinsic %s%s at bci:%d in",
|
||||
vmIntrinsics::name_at(intrinsic_id()),
|
||||
(is_virtual() ? " (virtual)" : ""), kit.bci());
|
||||
kit.caller()->print_short_name(tty);
|
||||
tty->print_cr(" (%d bytes)", kit.caller()->code_size());
|
||||
CompileTask::print_inlining(kit.callee(), jvms->depth() - 1, kit.bci(), is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
|
||||
}
|
||||
C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
|
||||
if (C->log()) {
|
||||
|
@ -396,16 +396,16 @@ void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) {
|
||||
// Return exact loop trip count, or 0 if not maximally unrolling
|
||||
bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
|
||||
CountedLoopNode *cl = _head->as_CountedLoop();
|
||||
assert( cl->is_normal_loop(), "" );
|
||||
assert(cl->is_normal_loop(), "");
|
||||
|
||||
Node *init_n = cl->init_trip();
|
||||
Node *limit_n = cl->limit();
|
||||
|
||||
// Non-constant bounds
|
||||
if( init_n == NULL || !init_n->is_Con() ||
|
||||
if (init_n == NULL || !init_n->is_Con() ||
|
||||
limit_n == NULL || !limit_n->is_Con() ||
|
||||
// protect against stride not being a constant
|
||||
!cl->stride_is_con() ) {
|
||||
!cl->stride_is_con()) {
|
||||
return false;
|
||||
}
|
||||
int init = init_n->get_int();
|
||||
@ -428,7 +428,31 @@ bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
|
||||
uint unroll_limit = (uint)LoopUnrollLimit * 4;
|
||||
assert( (intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits");
|
||||
cl->set_trip_count(trip_count);
|
||||
if( trip_count <= unroll_limit && body_size <= unroll_limit ) {
|
||||
if (trip_count > unroll_limit || body_size > unroll_limit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Currently we don't have policy to optimize one iteration loops.
|
||||
// Maximally unrolling transformation is used for that:
|
||||
// it is peeled and the original loop become non reachable (dead).
|
||||
if (trip_count == 1)
|
||||
return true;
|
||||
|
||||
// Do not unroll a loop with String intrinsics code.
|
||||
// String intrinsics are large and have loops.
|
||||
for (uint k = 0; k < _body.size(); k++) {
|
||||
Node* n = _body.at(k);
|
||||
switch (n->Opcode()) {
|
||||
case Op_StrComp:
|
||||
case Op_StrEquals:
|
||||
case Op_StrIndexOf:
|
||||
case Op_AryEq: {
|
||||
return false;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
|
||||
if (body_size <= unroll_limit) {
|
||||
uint new_body_size = body_size * trip_count;
|
||||
if (new_body_size <= unroll_limit &&
|
||||
body_size == new_body_size / trip_count &&
|
||||
@ -448,13 +472,13 @@ bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
|
||||
bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const {
|
||||
|
||||
CountedLoopNode *cl = _head->as_CountedLoop();
|
||||
assert( cl->is_normal_loop() || cl->is_main_loop(), "" );
|
||||
assert(cl->is_normal_loop() || cl->is_main_loop(), "");
|
||||
|
||||
// protect against stride not being a constant
|
||||
if( !cl->stride_is_con() ) return false;
|
||||
if (!cl->stride_is_con()) return false;
|
||||
|
||||
// protect against over-unrolling
|
||||
if( cl->trip_count() <= 1 ) return false;
|
||||
if (cl->trip_count() <= 1) return false;
|
||||
|
||||
int future_unroll_ct = cl->unrolled_count() * 2;
|
||||
|
||||
@ -485,21 +509,21 @@ bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const {
|
||||
// Non-constant bounds.
|
||||
// Protect against over-unrolling when init or/and limit are not constant
|
||||
// (so that trip_count's init value is maxint) but iv range is known.
|
||||
if( init_n == NULL || !init_n->is_Con() ||
|
||||
limit_n == NULL || !limit_n->is_Con() ) {
|
||||
if (init_n == NULL || !init_n->is_Con() ||
|
||||
limit_n == NULL || !limit_n->is_Con()) {
|
||||
Node* phi = cl->phi();
|
||||
if( phi != NULL ) {
|
||||
if (phi != NULL) {
|
||||
assert(phi->is_Phi() && phi->in(0) == _head, "Counted loop should have iv phi.");
|
||||
const TypeInt* iv_type = phase->_igvn.type(phi)->is_int();
|
||||
int next_stride = cl->stride_con() * 2; // stride after this unroll
|
||||
if( next_stride > 0 ) {
|
||||
if( iv_type->_lo + next_stride <= iv_type->_lo || // overflow
|
||||
iv_type->_lo + next_stride > iv_type->_hi ) {
|
||||
if (next_stride > 0) {
|
||||
if (iv_type->_lo + next_stride <= iv_type->_lo || // overflow
|
||||
iv_type->_lo + next_stride > iv_type->_hi) {
|
||||
return false; // over-unrolling
|
||||
}
|
||||
} else if( next_stride < 0 ) {
|
||||
if( iv_type->_hi + next_stride >= iv_type->_hi || // overflow
|
||||
iv_type->_hi + next_stride < iv_type->_lo ) {
|
||||
} else if (next_stride < 0) {
|
||||
if (iv_type->_hi + next_stride >= iv_type->_hi || // overflow
|
||||
iv_type->_hi + next_stride < iv_type->_lo) {
|
||||
return false; // over-unrolling
|
||||
}
|
||||
}
|
||||
@ -511,24 +535,33 @@ bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const {
|
||||
// Key test to unroll CaffeineMark's Logic test
|
||||
int xors_in_loop = 0;
|
||||
// Also count ModL, DivL and MulL which expand mightly
|
||||
for( uint k = 0; k < _body.size(); k++ ) {
|
||||
switch( _body.at(k)->Opcode() ) {
|
||||
case Op_XorI: xors_in_loop++; break; // CaffeineMark's Logic test
|
||||
case Op_ModL: body_size += 30; break;
|
||||
case Op_DivL: body_size += 30; break;
|
||||
case Op_MulL: body_size += 10; break;
|
||||
}
|
||||
for (uint k = 0; k < _body.size(); k++) {
|
||||
Node* n = _body.at(k);
|
||||
switch (n->Opcode()) {
|
||||
case Op_XorI: xors_in_loop++; break; // CaffeineMark's Logic test
|
||||
case Op_ModL: body_size += 30; break;
|
||||
case Op_DivL: body_size += 30; break;
|
||||
case Op_MulL: body_size += 10; break;
|
||||
case Op_StrComp:
|
||||
case Op_StrEquals:
|
||||
case Op_StrIndexOf:
|
||||
case Op_AryEq: {
|
||||
// Do not unroll a loop with String intrinsics code.
|
||||
// String intrinsics are large and have loops.
|
||||
return false;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
|
||||
// Check for being too big
|
||||
if( body_size > (uint)LoopUnrollLimit ) {
|
||||
if( xors_in_loop >= 4 && body_size < (uint)LoopUnrollLimit*4) return true;
|
||||
if (body_size > (uint)LoopUnrollLimit) {
|
||||
if (xors_in_loop >= 4 && body_size < (uint)LoopUnrollLimit*4) return true;
|
||||
// Normal case: loop too big
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for stride being a small enough constant
|
||||
if( abs(cl->stride_con()) > (1<<3) ) return false;
|
||||
if (abs(cl->stride_con()) > (1<<3)) return false;
|
||||
|
||||
// Unroll once! (Each trip will soon do double iterations)
|
||||
return true;
|
||||
@ -1608,15 +1641,7 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
|
||||
return false; // Malformed loop
|
||||
if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue))))
|
||||
return false; // Infinite loop
|
||||
#ifndef PRODUCT
|
||||
if (PrintOpto) {
|
||||
tty->print("Removing empty loop");
|
||||
this->dump_head();
|
||||
} else if (TraceLoopOpts) {
|
||||
tty->print("Empty ");
|
||||
this->dump_head();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ASSERT
|
||||
// Ensure only one phi which is the iv.
|
||||
Node* iv = NULL;
|
||||
@ -1629,6 +1654,43 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
|
||||
}
|
||||
assert(iv == cl->phi(), "Wrong phi" );
|
||||
#endif
|
||||
|
||||
// main and post loops have explicitly created zero trip guard
|
||||
bool needs_guard = !cl->is_main_loop() && !cl->is_post_loop();
|
||||
if (needs_guard) {
|
||||
// Check for an obvious zero trip guard.
|
||||
Node* inctrl = cl->in(LoopNode::EntryControl);
|
||||
if (inctrl->Opcode() == Op_IfTrue) {
|
||||
// The test should look like just the backedge of a CountedLoop
|
||||
Node* iff = inctrl->in(0);
|
||||
if (iff->is_If()) {
|
||||
Node* bol = iff->in(1);
|
||||
if (bol->is_Bool() && bol->as_Bool()->_test._test == cl->loopexit()->test_trip()) {
|
||||
Node* cmp = bol->in(1);
|
||||
if (cmp->is_Cmp() && cmp->in(1) == cl->init_trip() && cmp->in(2) == cl->limit()) {
|
||||
needs_guard = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (PrintOpto) {
|
||||
tty->print("Removing empty loop with%s zero trip guard", needs_guard ? "out" : "");
|
||||
this->dump_head();
|
||||
} else if (TraceLoopOpts) {
|
||||
tty->print("Empty with%s zero trip guard ", needs_guard ? "out" : "");
|
||||
this->dump_head();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (needs_guard) {
|
||||
// Peel the loop to ensure there's a zero trip guard
|
||||
Node_List old_new;
|
||||
phase->do_peeling(this, old_new);
|
||||
}
|
||||
|
||||
// Replace the phi at loop head with the final value of the last
|
||||
// iteration. Then the CountedLoopEnd will collapse (backedge never
|
||||
// taken) and all loop-invariant uses of the exit values will be correct.
|
||||
|
@ -1064,8 +1064,6 @@ bool IdealLoopTree::beautify_loops( PhaseIdealLoop *phase ) {
|
||||
// Cache parts in locals for easy
|
||||
PhaseIterGVN &igvn = phase->_igvn;
|
||||
|
||||
phase->C->print_method("Before beautify loops", 3);
|
||||
|
||||
igvn.hash_delete(_head); // Yank from hash before hacking edges
|
||||
|
||||
// Check for multiple fall-in paths. Peel off a landing pad if need be.
|
||||
@ -1547,6 +1545,7 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool do_loop_pred) {
|
||||
ResourceMark rm;
|
||||
|
||||
int old_progress = C->major_progress();
|
||||
uint orig_worklist_size = _igvn._worklist.size();
|
||||
|
||||
// Reset major-progress flag for the driver's heuristics
|
||||
C->clear_major_progress();
|
||||
@ -1610,6 +1609,7 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool do_loop_pred) {
|
||||
// Split shared headers and insert loop landing pads.
|
||||
// Do not bother doing this on the Root loop of course.
|
||||
if( !_verify_me && !_verify_only && _ltree_root->_child ) {
|
||||
C->print_method("Before beautify loops", 3);
|
||||
if( _ltree_root->_child->beautify_loops( this ) ) {
|
||||
// Re-build loop tree!
|
||||
_ltree_root->_child = NULL;
|
||||
@ -1694,7 +1694,7 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool do_loop_pred) {
|
||||
for (int i = 0; i < old_progress; i++)
|
||||
C->set_major_progress();
|
||||
assert(C->unique() == unique, "verification mode made Nodes? ? ?");
|
||||
assert(_igvn._worklist.size() == 0, "shouldn't push anything");
|
||||
assert(_igvn._worklist.size() == orig_worklist_size, "shouldn't push anything");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,9 @@
|
||||
#ifdef TARGET_ARCH_MODEL_zero
|
||||
# include "adfiles/ad_zero.hpp"
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_MODEL_arm
|
||||
# include "adfiles/ad_arm.hpp"
|
||||
#endif
|
||||
|
||||
OptoReg::Name OptoReg::c_frame_pointer;
|
||||
|
||||
|
@ -427,6 +427,11 @@ public:
|
||||
// Do ints take an entire long register or just half?
|
||||
static const bool int_in_long;
|
||||
|
||||
// Do the processor's shift instructions only use the low 5/6 bits
|
||||
// of the count for 32/64 bit ints? If not we need to do the masking
|
||||
// ourselves.
|
||||
static const bool need_masked_shift_count;
|
||||
|
||||
// This routine is run whenever a graph fails to match.
|
||||
// If it returns, the compiler should bailout to interpreter without error.
|
||||
// In non-product mode, SoftMatchFailure is false to detect non-canonical
|
||||
|
@ -2617,54 +2617,28 @@ Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest,
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Do we match on this edge? No memory edges
|
||||
uint StrCompNode::match_edge(uint idx) const {
|
||||
return idx == 2 || idx == 3; // StrComp (Binary str1 cnt1) (Binary str2 cnt2)
|
||||
// Do not match memory edge.
|
||||
uint StrIntrinsicNode::match_edge(uint idx) const {
|
||||
return idx == 2 || idx == 3;
|
||||
}
|
||||
|
||||
//------------------------------Ideal------------------------------------------
|
||||
// Return a node which is more "ideal" than the current node. Strip out
|
||||
// control copies
|
||||
Node *StrCompNode::Ideal(PhaseGVN *phase, bool can_reshape){
|
||||
return remove_dead_region(phase, can_reshape) ? this : NULL;
|
||||
}
|
||||
Node *StrIntrinsicNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
if (remove_dead_region(phase, can_reshape)) return this;
|
||||
|
||||
//=============================================================================
|
||||
// Do we match on this edge? No memory edges
|
||||
uint StrEqualsNode::match_edge(uint idx) const {
|
||||
return idx == 2 || idx == 3; // StrEquals (Binary str1 str2) cnt
|
||||
}
|
||||
|
||||
//------------------------------Ideal------------------------------------------
|
||||
// Return a node which is more "ideal" than the current node. Strip out
|
||||
// control copies
|
||||
Node *StrEqualsNode::Ideal(PhaseGVN *phase, bool can_reshape){
|
||||
return remove_dead_region(phase, can_reshape) ? this : NULL;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Do we match on this edge? No memory edges
|
||||
uint StrIndexOfNode::match_edge(uint idx) const {
|
||||
return idx == 2 || idx == 3; // StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)
|
||||
}
|
||||
|
||||
//------------------------------Ideal------------------------------------------
|
||||
// Return a node which is more "ideal" than the current node. Strip out
|
||||
// control copies
|
||||
Node *StrIndexOfNode::Ideal(PhaseGVN *phase, bool can_reshape){
|
||||
return remove_dead_region(phase, can_reshape) ? this : NULL;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Do we match on this edge? No memory edges
|
||||
uint AryEqNode::match_edge(uint idx) const {
|
||||
return idx == 2 || idx == 3; // StrEquals ary1 ary2
|
||||
}
|
||||
//------------------------------Ideal------------------------------------------
|
||||
// Return a node which is more "ideal" than the current node. Strip out
|
||||
// control copies
|
||||
Node *AryEqNode::Ideal(PhaseGVN *phase, bool can_reshape){
|
||||
return remove_dead_region(phase, can_reshape) ? this : NULL;
|
||||
if (can_reshape) {
|
||||
Node* mem = phase->transform(in(MemNode::Memory));
|
||||
// If transformed to a MergeMem, get the desired slice
|
||||
uint alias_idx = phase->C->get_alias_index(adr_type());
|
||||
mem = mem->is_MergeMem() ? mem->as_MergeMem()->memory_at(alias_idx) : mem;
|
||||
if (mem != in(MemNode::Memory)) {
|
||||
set_req(MemNode::Memory, mem);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -776,67 +776,69 @@ public:
|
||||
static bool step_through(Node** np, uint instance_id, PhaseTransform* phase);
|
||||
};
|
||||
|
||||
//------------------------------StrComp-------------------------------------
|
||||
class StrCompNode: public Node {
|
||||
//------------------------------StrIntrinsic-------------------------------
|
||||
// Base class for Ideal nodes used in String instrinsic code.
|
||||
class StrIntrinsicNode: public Node {
|
||||
public:
|
||||
StrCompNode(Node* control, Node* char_array_mem,
|
||||
Node* s1, Node* c1,
|
||||
Node* s2, Node* c2): Node(control, char_array_mem,
|
||||
s1, c1,
|
||||
s2, c2) {};
|
||||
virtual int Opcode() const;
|
||||
StrIntrinsicNode(Node* control, Node* char_array_mem,
|
||||
Node* s1, Node* c1, Node* s2, Node* c2):
|
||||
Node(control, char_array_mem, s1, c1, s2, c2) {
|
||||
}
|
||||
|
||||
StrIntrinsicNode(Node* control, Node* char_array_mem,
|
||||
Node* s1, Node* s2, Node* c):
|
||||
Node(control, char_array_mem, s1, s2, c) {
|
||||
}
|
||||
|
||||
StrIntrinsicNode(Node* control, Node* char_array_mem,
|
||||
Node* s1, Node* s2):
|
||||
Node(control, char_array_mem, s1, s2) {
|
||||
}
|
||||
|
||||
virtual bool depends_only_on_test() const { return false; }
|
||||
virtual const Type* bottom_type() const { return TypeInt::INT; }
|
||||
virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
|
||||
virtual uint match_edge(uint idx) const;
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
||||
};
|
||||
|
||||
//------------------------------StrComp-------------------------------------
|
||||
class StrCompNode: public StrIntrinsicNode {
|
||||
public:
|
||||
StrCompNode(Node* control, Node* char_array_mem,
|
||||
Node* s1, Node* c1, Node* s2, Node* c2):
|
||||
StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {};
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* bottom_type() const { return TypeInt::INT; }
|
||||
};
|
||||
|
||||
//------------------------------StrEquals-------------------------------------
|
||||
class StrEqualsNode: public Node {
|
||||
class StrEqualsNode: public StrIntrinsicNode {
|
||||
public:
|
||||
StrEqualsNode(Node* control, Node* char_array_mem,
|
||||
Node* s1, Node* s2, Node* c): Node(control, char_array_mem,
|
||||
s1, s2, c) {};
|
||||
Node* s1, Node* s2, Node* c):
|
||||
StrIntrinsicNode(control, char_array_mem, s1, s2, c) {};
|
||||
virtual int Opcode() const;
|
||||
virtual bool depends_only_on_test() const { return false; }
|
||||
virtual const Type* bottom_type() const { return TypeInt::BOOL; }
|
||||
virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
|
||||
virtual uint match_edge(uint idx) const;
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
||||
};
|
||||
|
||||
//------------------------------StrIndexOf-------------------------------------
|
||||
class StrIndexOfNode: public Node {
|
||||
class StrIndexOfNode: public StrIntrinsicNode {
|
||||
public:
|
||||
StrIndexOfNode(Node* control, Node* char_array_mem,
|
||||
Node* s1, Node* c1,
|
||||
Node* s2, Node* c2): Node(control, char_array_mem,
|
||||
s1, c1,
|
||||
s2, c2) {};
|
||||
Node* s1, Node* c1, Node* s2, Node* c2):
|
||||
StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {};
|
||||
virtual int Opcode() const;
|
||||
virtual bool depends_only_on_test() const { return false; }
|
||||
virtual const Type* bottom_type() const { return TypeInt::INT; }
|
||||
virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
|
||||
virtual uint match_edge(uint idx) const;
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
||||
};
|
||||
|
||||
//------------------------------AryEq---------------------------------------
|
||||
class AryEqNode: public Node {
|
||||
class AryEqNode: public StrIntrinsicNode {
|
||||
public:
|
||||
AryEqNode(Node* control, Node* char_array_mem,
|
||||
Node* s1, Node* s2): Node(control, char_array_mem, s1, s2) {};
|
||||
AryEqNode(Node* control, Node* char_array_mem, Node* s1, Node* s2):
|
||||
StrIntrinsicNode(control, char_array_mem, s1, s2) {};
|
||||
virtual int Opcode() const;
|
||||
virtual bool depends_only_on_test() const { return false; }
|
||||
virtual const Type* bottom_type() const { return TypeInt::BOOL; }
|
||||
virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
|
||||
virtual uint match_edge(uint idx) const;
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
||||
};
|
||||
|
||||
//------------------------------MemBar-----------------------------------------
|
||||
|
@ -1373,12 +1373,12 @@ static inline bool NotANode(const Node* n) {
|
||||
//------------------------------find------------------------------------------
|
||||
// Find a neighbor of this Node with the given _idx
|
||||
// If idx is negative, find its absolute value, following both _in and _out.
|
||||
static void find_recur( Node* &result, Node *n, int idx, bool only_ctrl,
|
||||
VectorSet &old_space, VectorSet &new_space ) {
|
||||
static void find_recur(Compile* C, Node* &result, Node *n, int idx, bool only_ctrl,
|
||||
VectorSet* old_space, VectorSet* new_space ) {
|
||||
int node_idx = (idx >= 0) ? idx : -idx;
|
||||
if (NotANode(n)) return; // Gracefully handle NULL, -1, 0xabababab, etc.
|
||||
// Contained in new_space or old_space?
|
||||
VectorSet *v = Compile::current()->node_arena()->contains(n) ? &new_space : &old_space;
|
||||
// Contained in new_space or old_space? Check old_arena first since it's mostly empty.
|
||||
VectorSet *v = C->old_arena()->contains(n) ? old_space : new_space;
|
||||
if( v->test(n->_idx) ) return;
|
||||
if( (int)n->_idx == node_idx
|
||||
debug_only(|| n->debug_idx() == node_idx) ) {
|
||||
@ -1390,19 +1390,23 @@ static void find_recur( Node* &result, Node *n, int idx, bool only_ctrl,
|
||||
v->set(n->_idx);
|
||||
for( uint i=0; i<n->len(); i++ ) {
|
||||
if( only_ctrl && !(n->is_Region()) && (n->Opcode() != Op_Root) && (i != TypeFunc::Control) ) continue;
|
||||
find_recur( result, n->in(i), idx, only_ctrl, old_space, new_space );
|
||||
find_recur(C, result, n->in(i), idx, only_ctrl, old_space, new_space );
|
||||
}
|
||||
// Search along forward edges also:
|
||||
if (idx < 0 && !only_ctrl) {
|
||||
for( uint j=0; j<n->outcnt(); j++ ) {
|
||||
find_recur( result, n->raw_out(j), idx, only_ctrl, old_space, new_space );
|
||||
find_recur(C, result, n->raw_out(j), idx, only_ctrl, old_space, new_space );
|
||||
}
|
||||
}
|
||||
#ifdef ASSERT
|
||||
// Search along debug_orig edges last:
|
||||
for (Node* orig = n->debug_orig(); orig != NULL && n != orig; orig = orig->debug_orig()) {
|
||||
if (NotANode(orig)) break;
|
||||
find_recur( result, orig, idx, only_ctrl, old_space, new_space );
|
||||
// Search along debug_orig edges last, checking for cycles
|
||||
Node* orig = n->debug_orig();
|
||||
if (orig != NULL) {
|
||||
do {
|
||||
if (NotANode(orig)) break;
|
||||
find_recur(C, result, orig, idx, only_ctrl, old_space, new_space );
|
||||
orig = orig->debug_orig();
|
||||
} while (orig != NULL && orig != n->debug_orig());
|
||||
}
|
||||
#endif //ASSERT
|
||||
}
|
||||
@ -1417,7 +1421,7 @@ Node* Node::find(int idx) const {
|
||||
ResourceArea *area = Thread::current()->resource_area();
|
||||
VectorSet old_space(area), new_space(area);
|
||||
Node* result = NULL;
|
||||
find_recur( result, (Node*) this, idx, false, old_space, new_space );
|
||||
find_recur(Compile::current(), result, (Node*) this, idx, false, &old_space, &new_space );
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1427,7 +1431,7 @@ Node* Node::find_ctrl(int idx) const {
|
||||
ResourceArea *area = Thread::current()->resource_area();
|
||||
VectorSet old_space(area), new_space(area);
|
||||
Node* result = NULL;
|
||||
find_recur( result, (Node*) this, idx, true, old_space, new_space );
|
||||
find_recur(Compile::current(), result, (Node*) this, idx, true, &old_space, &new_space );
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
@ -112,7 +112,7 @@ bool MethodHandles::spot_check_entry_names() {
|
||||
// MethodHandles::generate_adapters
|
||||
//
|
||||
void MethodHandles::generate_adapters() {
|
||||
if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL) return;
|
||||
if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL) return;
|
||||
|
||||
assert(_adapter_code == NULL, "generate only once");
|
||||
|
||||
@ -143,7 +143,7 @@ void MethodHandlesAdapterGenerator::generate() {
|
||||
|
||||
void MethodHandles::set_enabled(bool z) {
|
||||
if (_enabled != z) {
|
||||
guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles");
|
||||
guarantee(z && EnableInvokeDynamic, "can only enable once, and only if -XX:+EnableInvokeDynamic");
|
||||
_enabled = z;
|
||||
}
|
||||
}
|
||||
@ -2579,7 +2579,6 @@ static JNINativeMethod methods[] = {
|
||||
{CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
|
||||
};
|
||||
|
||||
// More entry points specifically for EnableInvokeDynamic.
|
||||
// FIXME: Remove methods2 after AllowTransitionalJSR292 is removed.
|
||||
static JNINativeMethod methods2[] = {
|
||||
{CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHN_registerBootstrap)},
|
||||
@ -2618,10 +2617,8 @@ static void hack_signatures(JNINativeMethod* methods, jint num_methods, const ch
|
||||
JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
|
||||
assert(MethodHandles::spot_check_entry_names(), "entry enum is OK");
|
||||
|
||||
// note: this explicit warning-producing stuff will be replaced by auto-detection of the JSR 292 classes
|
||||
|
||||
if (!EnableMethodHandles) {
|
||||
warning("JSR 292 method handles are disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable.");
|
||||
if (!EnableInvokeDynamic) {
|
||||
warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
|
||||
return; // bind nothing
|
||||
}
|
||||
|
||||
@ -2702,11 +2699,6 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
MethodHandles::set_enabled(true);
|
||||
}
|
||||
|
||||
if (!EnableInvokeDynamic) {
|
||||
warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable.");
|
||||
return; // bind nothing
|
||||
}
|
||||
|
||||
if (AllowTransitionalJSR292) {
|
||||
ThreadToNativeFromVM ttnfv(thread);
|
||||
|
||||
|
@ -1560,7 +1560,7 @@ JVM_ENTRY(void, JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (AnonymousClasses) {
|
||||
if (EnableInvokeDynamic) {
|
||||
env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
|
||||
if (env->ExceptionOccurred()) {
|
||||
if (PrintMiscellaneous && (Verbose || WizardMode)) {
|
||||
|
@ -2974,21 +2974,28 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
if (EnableInvokeDynamic && !EnableMethodHandles) {
|
||||
if (!FLAG_IS_DEFAULT(EnableMethodHandles)) {
|
||||
warning("forcing EnableMethodHandles true because EnableInvokeDynamic is true");
|
||||
// Transitional
|
||||
if (EnableMethodHandles || AnonymousClasses) {
|
||||
if (!EnableInvokeDynamic && !FLAG_IS_DEFAULT(EnableInvokeDynamic)) {
|
||||
warning("EnableMethodHandles and AnonymousClasses are obsolete. Keeping EnableInvokeDynamic disabled.");
|
||||
} else {
|
||||
EnableInvokeDynamic = true;
|
||||
}
|
||||
EnableMethodHandles = true;
|
||||
}
|
||||
if (EnableMethodHandles && !AnonymousClasses) {
|
||||
if (!FLAG_IS_DEFAULT(AnonymousClasses)) {
|
||||
warning("forcing AnonymousClasses true because EnableMethodHandles is true");
|
||||
|
||||
// JSR 292 is not supported before 1.7
|
||||
if (!JDK_Version::is_gte_jdk17x_version()) {
|
||||
if (EnableInvokeDynamic) {
|
||||
if (!FLAG_IS_DEFAULT(EnableInvokeDynamic)) {
|
||||
warning("JSR 292 is not supported before 1.7. Disabling support.");
|
||||
}
|
||||
EnableInvokeDynamic = false;
|
||||
}
|
||||
AnonymousClasses = true;
|
||||
}
|
||||
if ((EnableMethodHandles || AnonymousClasses) && ScavengeRootsInCode == 0) {
|
||||
|
||||
if (EnableInvokeDynamic && ScavengeRootsInCode == 0) {
|
||||
if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) {
|
||||
warning("forcing ScavengeRootsInCode non-zero because EnableMethodHandles or AnonymousClasses is true");
|
||||
warning("forcing ScavengeRootsInCode non-zero because EnableInvokeDynamic is true");
|
||||
}
|
||||
ScavengeRootsInCode = 1;
|
||||
}
|
||||
|
@ -396,8 +396,6 @@ void NonTieredCompPolicy::trace_osr_request(methodHandle method, nmethod* osr, i
|
||||
// SimpleCompPolicy - compile current method
|
||||
|
||||
void SimpleCompPolicy::method_invocation_event( methodHandle m, TRAPS) {
|
||||
assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now.");
|
||||
|
||||
int hot_count = m->invocation_count();
|
||||
reset_counter_for_invocation_event(m);
|
||||
const char* comment = "count";
|
||||
@ -413,8 +411,6 @@ void SimpleCompPolicy::method_invocation_event( methodHandle m, TRAPS) {
|
||||
}
|
||||
|
||||
void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, TRAPS) {
|
||||
assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now.");
|
||||
|
||||
int hot_count = m->backedge_count();
|
||||
const char* comment = "backedge_count";
|
||||
|
||||
@ -432,8 +428,6 @@ const char* StackWalkCompPolicy::_msg = NULL;
|
||||
|
||||
// Consider m for compilation
|
||||
void StackWalkCompPolicy::method_invocation_event(methodHandle m, TRAPS) {
|
||||
assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now.");
|
||||
|
||||
int hot_count = m->invocation_count();
|
||||
reset_counter_for_invocation_event(m);
|
||||
const char* comment = "count";
|
||||
@ -473,8 +467,6 @@ void StackWalkCompPolicy::method_invocation_event(methodHandle m, TRAPS) {
|
||||
}
|
||||
|
||||
void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, TRAPS) {
|
||||
assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now.");
|
||||
|
||||
int hot_count = m->backedge_count();
|
||||
const char* comment = "backedge_count";
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user