Merge
This commit is contained in:
commit
a37420e027
.hgtags.hgtags-top-repoREADME-builds.html
corba
hotspot
.hgtags
agent
src/share/classes/sun/jvm/hotspot
jdi
memory
oops
Instance.javaInstanceKlass.javaInstanceMirrorKlass.javaIntField.javaObjectHeap.javaOop.javaOopField.javaOopUtilities.javajava_lang_Class.java
runtime
tools
utilities
test/jdi
make
src
cpu
sparc/vm
c1_CodeStubs_sparc.cppcppInterpreter_sparc.cppdump_sparc.cppinterp_masm_sparc.cppinterpreter_sparc.cppmethodHandles_sparc.cppnativeInst_sparc.cppnativeInst_sparc.hpprelocInfo_sparc.cppsharedRuntime_sparc.cppsparc.adtemplateTable_sparc.cpp
x86/vm
assembler_x86.cppassembler_x86.hppc1_CodeStubs_x86.cppc1_LIRAssembler_x86.cppc1_Runtime1_x86.cppframe_x86.hppinterp_masm_x86_32.cppinterp_masm_x86_64.cppinterpreter_x86_32.cppinterpreter_x86_64.cppnativeInst_x86.hpprelocInfo_x86.cppsharedRuntime_x86_32.cppsharedRuntime_x86_64.cppstubGenerator_x86_64.cpptemplateInterpreter_x86_32.cpptemplateInterpreter_x86_64.cpptemplateTable_x86_32.cpptemplateTable_x86_64.cppvm_version_x86.cppx86_32.adx86_64.ad
zero/vm
os/windows/vm
share
tools/ProjectCreator
vm
2
.hgtags
2
.hgtags
@ -109,3 +109,5 @@ d8af56da89bc0fc02a6b6ad78f51157a46d665ab jdk7-b131
|
||||
d61280d36755d1941fb487f554e8b7a6d0bca6a1 jdk7-b132
|
||||
fd444c61e7ed3d92b2a730da7c737b02191b682f jdk7-b133
|
||||
def8e16dd237a47fc067d66d4c616d7baaec6001 jdk7-b134
|
||||
f75a1efb141210901aabe00a834e0fc32bb8b337 jdk7-b135
|
||||
46acf76a533954cfd594bb88fdea79938abfbe20 jdk7-b136
|
||||
|
@ -109,3 +109,5 @@ cc58c11af15411042719e9c82707fdbef60a9e0f jdk7-b130
|
||||
0f62a65fb666b337caa585015ab6ea2e60e709ca jdk7-b132
|
||||
c6f380693342feadccc5fe2c5adf500e861361aa jdk7-b133
|
||||
ddc2fcb3682ffd27f44354db666128827be7e3c3 jdk7-b134
|
||||
783bd02b4ab4596059c74b10a1793d7bd2f1c157 jdk7-b135
|
||||
2fe76e73adaa5133ac559f0b3c2c0707eca04580 jdk7-b136
|
||||
|
@ -1763,6 +1763,12 @@
|
||||
Where each of these directories contain the import JDK image
|
||||
for that platform.
|
||||
</dd>
|
||||
<dt><a name="ALT_OPENWIN_HOME"><tt>ALT_OPENWIN_HOME</tt></a></dt>
|
||||
<dd>
|
||||
The top-level directory of the libraries and include files for the platform's
|
||||
graphical programming environment. The default location is platform specific.
|
||||
For example, on Linux it defaults to <tt>/usr/X11R6/</tt>.
|
||||
</dd>
|
||||
<dt><strong>Windows specific:</strong></dt>
|
||||
<dd>
|
||||
<dl>
|
||||
@ -1791,6 +1797,81 @@
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><strong>Cross-Compilation Support:</strong></dt>
|
||||
<dd>
|
||||
<dl>
|
||||
<dt><a name="CROSS_COMPILE_ARCH"><tt>CROSS_COMPILE_ARCH</tt></a> </dt>
|
||||
<dd>
|
||||
Set to the target architecture of a cross-compilation build. If set, this
|
||||
variable is used to signify that we are cross-compiling. The expectation
|
||||
is that <a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a> is set
|
||||
to point to the cross-compiler and that any cross-compilation specific flags
|
||||
are passed using <a href="#EXTRA_CFLAGS"><tt>EXTRA_CFLAGS</tt></a>.
|
||||
The <a href="#ALT_OPENWIN_HOME"><tt>ALT_OPENWIN_HOME</tt></a> variable should
|
||||
also be set to point to the graphical header files (e.g. X11) provided with
|
||||
the cross-compiler.
|
||||
When cross-compiling we skip execution of any demos etc that may be built, and
|
||||
also skip binary-file verification.
|
||||
</dd>
|
||||
<dt><tt><a name="EXTRA_CFLAGS">EXTRA_CFLAGS</a></tt> </dt>
|
||||
<dd>
|
||||
Used to pass cross-compilation options to the cross-compiler.
|
||||
These are added to the <tt>CFLAGS</tt> and <tt>CXXFLAGS</tt> variables.
|
||||
</dd>
|
||||
<dt><tt><a name="USE_ONLY_BOOTDIR_TOOLS">USE_ONLY_BOOTDIR_TOOLS</a></tt> </dt>
|
||||
<dd>
|
||||
Used primarily for cross-compilation builds (and always set in that case)
|
||||
this variable indicates that tools from the boot JDK should be used during
|
||||
the build process, not the tools (<tt>javac</tt>, <tt>javah</tt>, <tt>jar</tt>)
|
||||
just built (which can't execute on the build host).
|
||||
</dd>
|
||||
<dt><tt><a name="HOST_CC">HOST_CC</a></tt> </dt>
|
||||
<dd>
|
||||
The location of the C compiler to generate programs to run on the build host.
|
||||
Some parts of the build generate programs that are then compiled and executed
|
||||
to produce other parts of the build. Normally the primary C compiler is used
|
||||
to do this, but when cross-compiling that would be the cross-compiler and the
|
||||
resulting program could not be executed.
|
||||
On Linux this defaults to <tt>/usr/bin/gcc</tt>; on other platforms it must be
|
||||
set explicitly.
|
||||
</dd>
|
||||
</dl>
|
||||
<dt><strong>Specialized Build Options:</strong></dt>
|
||||
<dd>
|
||||
Some build variables exist to support specialized build environments and/or specialized
|
||||
build products. Their use is only supported in those contexts:
|
||||
<dl>
|
||||
<dt><tt><a name="BUILD_CLIENT_ONLY">BUILD_CLIENT_ONLY</a></tt> </dt>
|
||||
<dd>
|
||||
Indicates this build will only contain the Hotspot client VM. In addition to
|
||||
controlling the Hotspot build target, it ensures that we don't try to copy
|
||||
any server VM files/directories, and defines a default <tt>jvm.cfg</tt> file
|
||||
suitable for a client-only environment. Using this in a 64-bit build will
|
||||
generate a sanity warning as 64-bit client builds are not directly supported.
|
||||
</dd>
|
||||
<dt><tt><a name="BUILD_HEADLESS_ONLY"></a>BUILD_HEADLESS_ONLY</tt> </dt>
|
||||
<dd>
|
||||
Used when the build environment has no graphical capabilities at all. This
|
||||
excludes building anything that requires graphical libraries to be available.
|
||||
</dd>
|
||||
<dt><tt><a name="JAVASE_EMBEDDED"></a>JAVASE_EMBEDDED</tt> </dt>
|
||||
<dd>
|
||||
Used to indicate this is a build of the Oracle Java SE Embedded product.
|
||||
This will enable the directives included in the SE-Embedded specific build
|
||||
files.
|
||||
</dd>
|
||||
<dt><tt><a name="LIBZIP_CAN_USE_MMAP">LIBZIP_CAN_USE_MMAP</a></tt> </dt>
|
||||
<dd>
|
||||
If set to false, disables the use of mmap by the zip utility. Otherwise,
|
||||
mmap will be used.
|
||||
</dd>
|
||||
<dt><tt><a name="COMPRESS_JARS"></a>COMPRESS_JARS</tt> </dt>
|
||||
<dd>
|
||||
If set to true, causes certain jar files that would otherwise be built without
|
||||
compression, to use compression.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</blockquote>
|
||||
<!-- ------------------------------------------------------ -->
|
||||
|
@ -109,3 +109,5 @@ d7532bcd3742f1576dd07ff9fbb535c9c9a276e9 jdk7-b126
|
||||
1b1e75e8f476e5c07f0d2b035993895e2603e1f0 jdk7-b132
|
||||
671fe2e623ffefb4b7c312be919fc71eb48c1df1 jdk7-b133
|
||||
918003855fa0dba5acf4bf1fe36526d2fc4c1ba8 jdk7-b134
|
||||
e0b72ae5dc5e824b342801c8d1d336a55eb54e2c jdk7-b135
|
||||
48ef0c712e7cbf272f47f9224db92a3c6a9e2612 jdk7-b136
|
||||
|
@ -156,3 +156,7 @@ a8d643a4db47c7b58e0bcb49c77b5c3610de86a8 hs21-b03
|
||||
1b3a350709e4325d759bb453ff3fb6a463270488 jdk7-b133
|
||||
447e6faab4a8755d4860c2366630729dbaec111c jdk7-b134
|
||||
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) 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
|
||||
@ -62,7 +62,7 @@ public class FieldImpl extends TypeComponentImpl implements Field {
|
||||
|
||||
// get the value of static field
|
||||
ValueImpl getValue() {
|
||||
return getValue(saField.getFieldHolder());
|
||||
return getValue(saField.getFieldHolder().getJavaMirror());
|
||||
}
|
||||
|
||||
// get the value of this Field from a specific Oop
|
||||
|
@ -44,12 +44,10 @@ public class StringTable extends sun.jvm.hotspot.utilities.Hashtable {
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("StringTable");
|
||||
theTableField = type.getAddressField("_the_table");
|
||||
stringTableSize = db.lookupIntConstant("StringTable::string_table_size").intValue();
|
||||
}
|
||||
|
||||
// Fields
|
||||
private static AddressField theTableField;
|
||||
private static int stringTableSize;
|
||||
|
||||
// Accessors
|
||||
public static StringTable getTheTable() {
|
||||
@ -57,10 +55,6 @@ public class StringTable extends sun.jvm.hotspot.utilities.Hashtable {
|
||||
return (StringTable) VMObjectFactory.newObject(StringTable.class, tmp);
|
||||
}
|
||||
|
||||
public static int getStringTableSize() {
|
||||
return stringTableSize;
|
||||
}
|
||||
|
||||
public StringTable(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
@ -87,7 +87,7 @@ public class InstanceKlass extends Klass {
|
||||
innerClasses = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize());
|
||||
nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize());
|
||||
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
|
||||
staticOopFieldSize = new CIntField(type.getCIntegerField("_static_oop_field_size"), Oop.getHeaderSize());
|
||||
staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize());
|
||||
nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize());
|
||||
isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize());
|
||||
initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize());
|
||||
@ -140,7 +140,7 @@ public class InstanceKlass extends Klass {
|
||||
private static OopField innerClasses;
|
||||
private static CIntField nonstaticFieldSize;
|
||||
private static CIntField staticFieldSize;
|
||||
private static CIntField staticOopFieldSize;
|
||||
private static CIntField staticOopFieldCount;
|
||||
private static CIntField nonstaticOopMapSize;
|
||||
private static CIntField isMarkedDependent;
|
||||
private static CIntField initState;
|
||||
@ -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
|
||||
@ -261,8 +265,7 @@ public class InstanceKlass extends Klass {
|
||||
public Symbol getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
|
||||
public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); }
|
||||
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
|
||||
public long getStaticFieldSize() { return staticFieldSize.getValue(this); }
|
||||
public long getStaticOopFieldSize() { return staticOopFieldSize.getValue(this); }
|
||||
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
|
||||
public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); }
|
||||
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
|
||||
public long getVtableLen() { return vtableLen.getValue(this); }
|
||||
@ -453,14 +456,29 @@ public class InstanceKlass extends Klass {
|
||||
visitor.doOop(innerClasses, true);
|
||||
visitor.doCInt(nonstaticFieldSize, true);
|
||||
visitor.doCInt(staticFieldSize, true);
|
||||
visitor.doCInt(staticOopFieldSize, true);
|
||||
visitor.doCInt(staticOopFieldCount, true);
|
||||
visitor.doCInt(nonstaticOopMapSize, true);
|
||||
visitor.doCInt(isMarkedDependent, true);
|
||||
visitor.doCInt(initState, true);
|
||||
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) {
|
||||
@ -478,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();
|
||||
|
||||
@ -692,7 +710,7 @@ public class InstanceKlass extends Klass {
|
||||
public long getObjectSize() {
|
||||
long bodySize = alignObjectOffset(getVtableLen() * getHeap().getOopSize())
|
||||
+ alignObjectOffset(getItableLen() * getHeap().getOopSize())
|
||||
+ (getStaticFieldSize() + getNonstaticOopMapSize()) * getHeap().getOopSize();
|
||||
+ (getNonstaticOopMapSize()) * getHeap().getOopSize();
|
||||
return alignObjectSize(headerSize + bodySize);
|
||||
}
|
||||
|
||||
|
@ -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, 2001, 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
|
||||
@ -40,7 +40,12 @@ public class IntField extends Field {
|
||||
super(holder, fieldArrayIndex);
|
||||
}
|
||||
|
||||
public int getValue(Oop obj) { return obj.getHandle().getJIntAt(getOffset()); }
|
||||
public int getValue(Oop obj) {
|
||||
if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
|
||||
throw new InternalError(obj.toString());
|
||||
}
|
||||
return obj.getHandle().getJIntAt(getOffset());
|
||||
}
|
||||
public void setValue(Oop obj, int value) throws MutationException {
|
||||
// Fix this: setJIntAt is missing in Address
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2002, 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
|
||||
@ -41,11 +41,17 @@ public class OopField extends Field {
|
||||
}
|
||||
|
||||
public Oop getValue(Oop obj) {
|
||||
if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
|
||||
throw new InternalError();
|
||||
}
|
||||
return obj.getHeap().newOop(getValueAsOopHandle(obj));
|
||||
}
|
||||
|
||||
/** Debugging support */
|
||||
public OopHandle getValueAsOopHandle(Oop obj) {
|
||||
if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
|
||||
throw new InternalError(obj.toString());
|
||||
}
|
||||
return obj.getHandle().getOopHandleAt(getOffset());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -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,33 +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) Instance.getHeaderSize();
|
||||
try {
|
||||
hcKlassOffset += (db.lookupIntConstant("java_lang_Class::hc_klass_offset").intValue() *
|
||||
VM.getVM().getHeapOopSize());
|
||||
} catch (RuntimeException re) {
|
||||
// ignore, currently java_lang_Class::hc_klass_offset is zero
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
@ -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
|
||||
@ -839,20 +839,18 @@ public class VM {
|
||||
}
|
||||
|
||||
private void readSystemProperties() {
|
||||
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(getObj()));
|
||||
} 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) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2008, 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
|
||||
@ -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) {
|
||||
@ -746,7 +746,7 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
out.writeByte((byte)kind);
|
||||
if (ik != null) {
|
||||
// static field
|
||||
writeField(field, ik);
|
||||
writeField(field, ik.getJavaMirror());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -43,6 +43,7 @@ if [ "$1" == "-help" ]; then
|
||||
fi
|
||||
|
||||
jdk=$1
|
||||
shift
|
||||
OS=`uname`
|
||||
|
||||
if [ "$OS" != "Linux" ]; then
|
||||
@ -68,7 +69,7 @@ fi
|
||||
|
||||
tmp=/tmp/sagsetup
|
||||
rm -f $tmp
|
||||
$jdk/bin/java sagtarg > $tmp &
|
||||
$jdk/bin/java $* sagtarg > $tmp &
|
||||
pid=$!
|
||||
while [ ! -s $tmp ] ; do
|
||||
# Kludge alert!
|
||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
|
||||
|
||||
HS_MAJOR_VER=21
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=05
|
||||
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
|
||||
|
||||
|
@ -301,7 +301,8 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
|
||||
// thread.
|
||||
assert(_obj != noreg, "must be a valid register");
|
||||
assert(_oop_index >= 0, "must have oop index");
|
||||
__ ld_ptr(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
|
||||
__ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3);
|
||||
__ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
|
||||
__ cmp(G2_thread, G3);
|
||||
__ br(Assembler::notEqual, false, Assembler::pn, call_patch);
|
||||
__ delayed()->nop();
|
||||
|
@ -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);
|
||||
|
@ -80,13 +80,19 @@ void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list,
|
||||
for (int j = 0; j < num_virtuals; ++j) {
|
||||
dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
|
||||
__ save(SP, -256, SP);
|
||||
int offset = (i << 8) + j;
|
||||
Register src = G0;
|
||||
if (!Assembler::is_simm13(offset)) {
|
||||
__ sethi(offset, L0);
|
||||
src = L0;
|
||||
offset = offset & ((1 << 10) - 1);
|
||||
}
|
||||
__ brx(Assembler::always, false, Assembler::pt, common_code);
|
||||
|
||||
// Load L0 with a value indicating vtable/offset pair.
|
||||
// -- bits[ 7..0] (8 bits) which virtual method in table?
|
||||
// -- bits[12..8] (5 bits) which virtual method table?
|
||||
// -- must fit in 13-bit instruction immediate field.
|
||||
__ delayed()->set((i << 8) + j, L0);
|
||||
// -- bits[13..8] (6 bits) which virtual method table?
|
||||
__ delayed()->or3(src, offset, L0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -775,9 +775,13 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
|
||||
switch (ek) {
|
||||
case _adapter_opt_i2l:
|
||||
{
|
||||
__ ldsw(arg_lsw, O2_scratch); // Load LSW
|
||||
NOT_LP64(__ srlx(O2_scratch, BitsPerInt, O3_scratch)); // Move high bits to lower bits for std
|
||||
__ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64
|
||||
#ifdef _LP64
|
||||
__ ldsw(arg_lsw, O2_scratch); // Load LSW sign-extended
|
||||
#else
|
||||
__ ldsw(arg_lsw, O3_scratch); // Load LSW sign-extended
|
||||
__ srlx(O3_scratch, BitsPerInt, O2_scratch); // Move MSW value to lower 32-bits for std
|
||||
#endif
|
||||
__ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64
|
||||
}
|
||||
break;
|
||||
case _adapter_opt_unboxl:
|
||||
|
@ -52,6 +52,22 @@ void NativeInstruction::set_data64_sethi(address instaddr, intptr_t x) {
|
||||
ICache::invalidate_range(instaddr, 7 * BytesPerInstWord);
|
||||
}
|
||||
|
||||
void NativeInstruction::verify_data64_sethi(address instaddr, intptr_t x) {
|
||||
ResourceMark rm;
|
||||
unsigned char buffer[10 * BytesPerInstWord];
|
||||
CodeBuffer buf(buffer, 10 * BytesPerInstWord);
|
||||
MacroAssembler masm(&buf);
|
||||
|
||||
Register destreg = inv_rd(*(unsigned int *)instaddr);
|
||||
// Generate the proper sequence into a temporary buffer and compare
|
||||
// it with the original sequence.
|
||||
masm.patchable_sethi(x, destreg);
|
||||
int len = buffer - masm.pc();
|
||||
for (int i = 0; i < len; i++) {
|
||||
assert(instaddr[i] == buffer[i], "instructions must match");
|
||||
}
|
||||
}
|
||||
|
||||
void NativeInstruction::verify() {
|
||||
// make sure code pattern is actually an instruction address
|
||||
address addr = addr_at(0);
|
||||
|
@ -254,6 +254,7 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
|
||||
// sethi. This only does the sethi. The disp field (bottom 10 bits)
|
||||
// must be handled separately.
|
||||
static void set_data64_sethi(address instaddr, intptr_t x);
|
||||
static void verify_data64_sethi(address instaddr, intptr_t x);
|
||||
|
||||
// combine the fields of a sethi/simm13 pair (simm13 = or, add, jmpl, ld/st)
|
||||
static int data32(int sethi_insn, int arith_insn) {
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
|
||||
void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
|
||||
NativeInstruction* ip = nativeInstruction_at(addr());
|
||||
jint inst = ip->long_at(0);
|
||||
assert(inst != NativeInstruction::illegal_instruction(), "no breakpoint");
|
||||
@ -83,7 +83,11 @@ void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
guarantee(Assembler::is_simm13(simm13), "offset can't overflow simm13");
|
||||
inst &= ~Assembler::simm( -1, 13);
|
||||
inst |= Assembler::simm(simm13, 13);
|
||||
ip->set_long_at(0, inst);
|
||||
if (verify_only) {
|
||||
assert(ip->long_at(0) == inst, "instructions must match");
|
||||
} else {
|
||||
ip->set_long_at(0, inst);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -97,19 +101,36 @@ void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
jint np = oopDesc::encode_heap_oop((oop)x);
|
||||
inst &= ~Assembler::hi22(-1);
|
||||
inst |= Assembler::hi22((intptr_t)np);
|
||||
ip->set_long_at(0, inst);
|
||||
if (verify_only) {
|
||||
assert(ip->long_at(0) == inst, "instructions must match");
|
||||
} else {
|
||||
ip->set_long_at(0, inst);
|
||||
}
|
||||
inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
|
||||
guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
|
||||
ip->set_long_at(NativeInstruction::nop_instruction_size, ip->set_data32_simm13( inst2, (intptr_t)np));
|
||||
if (verify_only) {
|
||||
assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
|
||||
"instructions must match");
|
||||
} else {
|
||||
ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np));
|
||||
}
|
||||
break;
|
||||
}
|
||||
ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
|
||||
if (verify_only) {
|
||||
ip->verify_data64_sethi( ip->addr_at(0), (intptr_t)x );
|
||||
} else {
|
||||
ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
|
||||
}
|
||||
#else
|
||||
guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
|
||||
inst &= ~Assembler::hi22( -1);
|
||||
inst |= Assembler::hi22((intptr_t)x);
|
||||
// (ignore offset; it doesn't play into the sethi)
|
||||
ip->set_long_at(0, inst);
|
||||
if (verify_only) {
|
||||
assert(ip->long_at(0) == inst, "instructions must match");
|
||||
} else {
|
||||
ip->set_long_at(0, inst);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
@ -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);
|
||||
|
@ -313,10 +313,13 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
|
||||
}
|
||||
assert(_obj != noreg, "must be a valid register");
|
||||
Register tmp = rax;
|
||||
if (_obj == tmp) tmp = rbx;
|
||||
Register tmp2 = rbx;
|
||||
__ push(tmp);
|
||||
__ push(tmp2);
|
||||
__ load_heap_oop(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
|
||||
__ get_thread(tmp);
|
||||
__ cmpptr(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
|
||||
__ cmpptr(tmp, Address(tmp2, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
|
||||
__ pop(tmp2);
|
||||
__ pop(tmp);
|
||||
__ jcc(Assembler::notEqual, call_patch);
|
||||
|
||||
|
@ -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
|
||||
@ -31,7 +31,7 @@
|
||||
#include "runtime/safepoint.hpp"
|
||||
|
||||
|
||||
void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
|
||||
#ifdef AMD64
|
||||
x += o;
|
||||
typedef Assembler::WhichOperand WhichOperand;
|
||||
@ -40,19 +40,35 @@ void Relocation::pd_set_data_value(address x, intptr_t o) {
|
||||
which == Assembler::narrow_oop_operand ||
|
||||
which == Assembler::imm_operand, "format unpacks ok");
|
||||
if (which == Assembler::imm_operand) {
|
||||
*pd_address_in_code() = x;
|
||||
if (verify_only) {
|
||||
assert(*pd_address_in_code() == x, "instructions must match");
|
||||
} else {
|
||||
*pd_address_in_code() = x;
|
||||
}
|
||||
} else if (which == Assembler::narrow_oop_operand) {
|
||||
address disp = Assembler::locate_operand(addr(), which);
|
||||
*(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
|
||||
if (verify_only) {
|
||||
assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match");
|
||||
} else {
|
||||
*(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
|
||||
}
|
||||
} else {
|
||||
// Note: Use runtime_call_type relocations for call32_operand.
|
||||
address ip = addr();
|
||||
address disp = Assembler::locate_operand(ip, which);
|
||||
address next_ip = Assembler::locate_next_instruction(ip);
|
||||
*(int32_t*) disp = x - next_ip;
|
||||
if (verify_only) {
|
||||
assert(*(int32_t*) disp == (x - next_ip), "instructions must match");
|
||||
} else {
|
||||
*(int32_t*) disp = x - next_ip;
|
||||
}
|
||||
}
|
||||
#else
|
||||
*pd_address_in_code() = x + o;
|
||||
if (verify_only) {
|
||||
assert(*pd_address_in_code() == (x + o), "instructions must match");
|
||||
} else {
|
||||
*pd_address_in_code() = x + o;
|
||||
}
|
||||
#endif // AMD64
|
||||
}
|
||||
|
||||
@ -182,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);
|
||||
%}
|
||||
|
||||
|
@ -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.
|
||||
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -281,7 +281,7 @@ int CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
|
||||
if (method->is_static()) {
|
||||
istate->set_oop_temp(
|
||||
method->constants()->pool_holder()->klass_part()->java_mirror());
|
||||
method->constants()->pool_holder()->java_mirror());
|
||||
mirror = istate->oop_temp_addr();
|
||||
*(dst++) = &mirror;
|
||||
}
|
||||
@ -667,7 +667,7 @@ InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) {
|
||||
(BasicObjectLock *) stack->alloc(monitor_words * wordSize);
|
||||
oop object;
|
||||
if (method->is_static())
|
||||
object = method->constants()->pool_holder()->klass_part()->java_mirror();
|
||||
object = method->constants()->pool_holder()->java_mirror();
|
||||
else
|
||||
object = (oop) locals[0];
|
||||
monitor->set_obj(object);
|
||||
|
@ -3297,9 +3297,14 @@ bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
|
||||
"possibility of dangling Thread pointer");
|
||||
|
||||
OSThread* osthread = thread->osthread();
|
||||
bool interrupted;
|
||||
interrupted = osthread->interrupted();
|
||||
if (clear_interrupted == true) {
|
||||
bool interrupted = osthread->interrupted();
|
||||
// There is no synchronization between the setting of the interrupt
|
||||
// and it being cleared here. It is critical - see 6535709 - that
|
||||
// we only clear the interrupt state, and reset the interrupt event,
|
||||
// if we are going to report that we were indeed interrupted - else
|
||||
// an interrupt can be "lost", leading to spurious wakeups or lost wakeups
|
||||
// depending on the timing
|
||||
if (interrupted && clear_interrupted) {
|
||||
osthread->set_interrupted(false);
|
||||
ResetEvent(osthread->interrupt_event());
|
||||
} // Otherwise leave the interrupted state alone
|
||||
|
@ -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"
|
||||
@ -1471,9 +1472,9 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
|
||||
if (state_before != NULL) {
|
||||
// build a patching constant
|
||||
obj = new Constant(new ClassConstant(holder), state_before);
|
||||
obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before);
|
||||
} else {
|
||||
obj = new Constant(new ClassConstant(holder));
|
||||
obj = new Constant(new InstanceConstant(holder->java_mirror()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
@ -808,7 +808,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
||||
{ klassOop klass = resolve_field_return_klass(caller_method, bci, CHECK);
|
||||
// Save a reference to the class that has to be checked for initialization
|
||||
init_klass = KlassHandle(THREAD, klass);
|
||||
k = klass;
|
||||
k = klass->java_mirror();
|
||||
}
|
||||
break;
|
||||
case Bytecodes::_new:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 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
|
||||
@ -46,8 +46,7 @@ size_t ciCPCache::get_f1_offset(int index) {
|
||||
// ciCPCache::is_f1_null_at
|
||||
bool ciCPCache::is_f1_null_at(int index) {
|
||||
VM_ENTRY_MARK;
|
||||
oop f1 = entry_at(index)->f1();
|
||||
return (f1 == NULL);
|
||||
return entry_at(index)->is_f1_null();
|
||||
}
|
||||
|
||||
|
||||
|
@ -213,7 +213,7 @@ void ciField::initialize_from(fieldDescriptor* fd) {
|
||||
// may change. The three examples are java.lang.System.in,
|
||||
// java.lang.System.out, and java.lang.System.err.
|
||||
|
||||
Handle k = _holder->get_klassOop();
|
||||
KlassHandle k = _holder->get_klassOop();
|
||||
assert( SystemDictionary::System_klass() != NULL, "Check once per vm");
|
||||
if( k() == SystemDictionary::System_klass() ) {
|
||||
// Check offsets for case 2: System.in, System.out, or System.err
|
||||
@ -225,36 +225,38 @@ void ciField::initialize_from(fieldDescriptor* fd) {
|
||||
}
|
||||
}
|
||||
|
||||
Handle mirror = k->java_mirror();
|
||||
|
||||
_is_constant = true;
|
||||
switch(type()->basic_type()) {
|
||||
case T_BYTE:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->byte_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset));
|
||||
break;
|
||||
case T_CHAR:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->char_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset));
|
||||
break;
|
||||
case T_SHORT:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->short_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset));
|
||||
break;
|
||||
case T_BOOLEAN:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->bool_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset));
|
||||
break;
|
||||
case T_INT:
|
||||
_constant_value = ciConstant(type()->basic_type(), k->int_field(_offset));
|
||||
_constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset));
|
||||
break;
|
||||
case T_FLOAT:
|
||||
_constant_value = ciConstant(k->float_field(_offset));
|
||||
_constant_value = ciConstant(mirror->float_field(_offset));
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
_constant_value = ciConstant(k->double_field(_offset));
|
||||
_constant_value = ciConstant(mirror->double_field(_offset));
|
||||
break;
|
||||
case T_LONG:
|
||||
_constant_value = ciConstant(k->long_field(_offset));
|
||||
_constant_value = ciConstant(mirror->long_field(_offset));
|
||||
break;
|
||||
case T_OBJECT:
|
||||
case T_ARRAY:
|
||||
{
|
||||
oop o = k->obj_field(_offset);
|
||||
oop o = mirror->obj_field(_offset);
|
||||
|
||||
// A field will be "constant" if it is known always to be
|
||||
// a non-null reference to an instance of a particular class,
|
||||
|
@ -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
|
||||
@ -138,3 +138,9 @@ void ciInstance::print_impl(outputStream* st) {
|
||||
st->print(" type=");
|
||||
klass()->print(st);
|
||||
}
|
||||
|
||||
|
||||
ciKlass* ciInstance::java_lang_Class_klass() {
|
||||
VM_ENTRY_MARK;
|
||||
return CURRENT_ENV->get_object(java_lang_Class::as_klassOop(get_oop()))->as_klass();
|
||||
}
|
||||
|
@ -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
|
||||
@ -64,6 +64,8 @@ public:
|
||||
|
||||
// Constant value of a field at the specified offset.
|
||||
ciConstant field_value_by_offset(int field_offset);
|
||||
|
||||
ciKlass* java_lang_Class_klass();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_CI_CIINSTANCE_HPP
|
||||
|
@ -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
|
||||
@ -85,7 +85,6 @@ ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
|
||||
if (h_k() != SystemDictionary::Object_klass()) {
|
||||
super();
|
||||
}
|
||||
java_mirror();
|
||||
//compute_nonstatic_fields(); // done outside of constructor
|
||||
}
|
||||
|
||||
@ -320,6 +319,9 @@ ciInstanceKlass* ciInstanceKlass::super() {
|
||||
// Get the instance of java.lang.Class corresponding to this klass.
|
||||
// Cache it on this->_java_mirror.
|
||||
ciInstance* ciInstanceKlass::java_mirror() {
|
||||
if (is_shared()) {
|
||||
return ciKlass::java_mirror();
|
||||
}
|
||||
if (_java_mirror == NULL) {
|
||||
_java_mirror = ciKlass::java_mirror();
|
||||
}
|
||||
|
@ -663,7 +663,7 @@ ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
|
||||
if (key->is_perm() && _non_perm_count == 0) {
|
||||
return emptyBucket;
|
||||
} else if (key->is_instance()) {
|
||||
if (key->klass() == SystemDictionary::Class_klass()) {
|
||||
if (key->klass() == SystemDictionary::Class_klass() && JavaObjectsInPerm) {
|
||||
// class mirror instances are always perm
|
||||
return emptyBucket;
|
||||
}
|
||||
|
@ -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(" ==================================================== ");
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "memory/universe.inline.hpp"
|
||||
#include "oops/constantPoolOop.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/instanceMirrorKlass.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/klassOop.hpp"
|
||||
#include "oops/klassVtable.hpp"
|
||||
@ -151,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);
|
||||
@ -259,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",
|
||||
@ -442,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);
|
||||
@ -486,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));
|
||||
}
|
||||
@ -521,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
|
||||
@ -676,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()) {
|
||||
|
||||
@ -2102,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);
|
||||
@ -2606,54 +2607,6 @@ typeArrayHandle ClassFileParser::assemble_annotations(u1* runtime_visible_annota
|
||||
}
|
||||
|
||||
|
||||
static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
|
||||
KlassHandle h_k (THREAD, fd->field_holder());
|
||||
assert(h_k.not_null() && fd->is_static(), "just checking");
|
||||
if (fd->has_initial_value()) {
|
||||
BasicType t = fd->field_type();
|
||||
switch (t) {
|
||||
case T_BYTE:
|
||||
h_k()->byte_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_BOOLEAN:
|
||||
h_k()->bool_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_CHAR:
|
||||
h_k()->char_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_SHORT:
|
||||
h_k()->short_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_INT:
|
||||
h_k()->int_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_FLOAT:
|
||||
h_k()->float_field_put(fd->offset(), fd->float_initial_value());
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
h_k()->double_field_put(fd->offset(), fd->double_initial_value());
|
||||
break;
|
||||
case T_LONG:
|
||||
h_k()->long_field_put(fd->offset(), fd->long_initial_value());
|
||||
break;
|
||||
case T_OBJECT:
|
||||
{
|
||||
#ifdef ASSERT
|
||||
TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK);
|
||||
assert(fd->signature() == sym, "just checking");
|
||||
#endif
|
||||
oop string = fd->string_initial_value(CHECK);
|
||||
h_k()->obj_field_put(fd->offset(), string);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
THROW_MSG(vmSymbols::java_lang_ClassFormatError(),
|
||||
"Illegal ConstantValue attribute in class file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
|
||||
constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS) {
|
||||
// This code is for compatibility with earlier jdk's that do not
|
||||
@ -2769,8 +2722,8 @@ void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_pt
|
||||
}
|
||||
|
||||
|
||||
void ClassFileParser::java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
|
||||
FieldAllocationCount *fac_ptr, TRAPS) {
|
||||
void ClassFileParser::java_lang_Class_fix_pre(int* nonstatic_field_size,
|
||||
FieldAllocationCount *fac_ptr) {
|
||||
// Add fake fields for java.lang.Class instances
|
||||
//
|
||||
// This is not particularly nice. We should consider adding a
|
||||
@ -2787,10 +2740,13 @@ void ClassFileParser::java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
|
||||
// versions because when the offsets are computed at bootstrap
|
||||
// time we don't know yet which version of the JDK we're running in.
|
||||
|
||||
// The values below are fake but will force two non-static oop fields and
|
||||
// The values below are fake but will force three non-static oop fields and
|
||||
// a corresponding non-static oop map block to be allocated.
|
||||
const int extra = java_lang_Class::number_of_fake_oop_fields;
|
||||
fac_ptr->nonstatic_oop_count += extra;
|
||||
|
||||
// Reserve some leading space for fake ints
|
||||
*nonstatic_field_size += align_size_up(java_lang_Class::hc_number_of_fake_int_fields * BytesPerInt, heapOopSize) / heapOopSize;
|
||||
}
|
||||
|
||||
|
||||
@ -2815,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();
|
||||
@ -3205,9 +3161,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
int next_nonstatic_field_offset;
|
||||
|
||||
// Calculate the starting byte offsets
|
||||
next_static_oop_offset = (instanceKlass::header_size() +
|
||||
align_object_offset(vtable_size) +
|
||||
align_object_offset(itable_size)) * wordSize;
|
||||
next_static_oop_offset = instanceMirrorKlass::offset_of_static_fields();
|
||||
next_static_double_offset = next_static_oop_offset +
|
||||
(fac.static_oop_count * heapOopSize);
|
||||
if ( fac.static_double_count &&
|
||||
@ -3226,25 +3180,26 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
fac.static_byte_count ), wordSize );
|
||||
static_field_size = (next_static_type_offset -
|
||||
next_static_oop_offset) / wordSize;
|
||||
|
||||
// Add fake fields for java.lang.Class instances (also see below)
|
||||
if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
|
||||
java_lang_Class_fix_pre(&nonstatic_field_size, &fac);
|
||||
}
|
||||
|
||||
first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
|
||||
nonstatic_field_size * heapOopSize;
|
||||
next_nonstatic_field_offset = first_nonstatic_field_offset;
|
||||
|
||||
// Add fake fields for java.lang.Class instances (also see below)
|
||||
if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
|
||||
java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
@ -3566,7 +3521,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
}
|
||||
|
||||
// We can now create the basic klassOop for this klass
|
||||
klassOop ik = oopFactory::new_instanceKlass(vtable_size, itable_size,
|
||||
klassOop ik = oopFactory::new_instanceKlass(name, vtable_size, itable_size,
|
||||
static_field_size,
|
||||
total_oop_map_count,
|
||||
rt, CHECK_(nullHandle));
|
||||
@ -3588,7 +3543,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
this_klass->set_class_loader(class_loader());
|
||||
this_klass->set_nonstatic_field_size(nonstatic_field_size);
|
||||
this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
|
||||
this_klass->set_static_oop_field_size(fac.static_oop_count);
|
||||
this_klass->set_static_oop_field_count(fac.static_oop_count);
|
||||
cp->set_pool_holder(this_klass());
|
||||
error_handler.set_in_error(false); // turn off error handler for cp
|
||||
this_klass->set_constants(cp());
|
||||
@ -3649,9 +3604,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
// Make sure this is the end of class file stream
|
||||
guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
|
||||
|
||||
// Initialize static fields
|
||||
this_klass->do_local_static_fields(&initialize_static_field, CHECK_(nullHandle));
|
||||
|
||||
// VerifyOops believes that once this has been set, the object is completely loaded.
|
||||
// Compute transitive closure of interfaces this class implements
|
||||
this_klass->set_transitive_interfaces(transitive_interfaces());
|
||||
@ -3685,6 +3637,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
check_illegal_static_method(this_klass, CHECK_(nullHandle));
|
||||
}
|
||||
|
||||
// Allocate mirror and initialize static fields
|
||||
java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
|
||||
|
||||
ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()),
|
||||
false /* not shared class */);
|
||||
|
||||
|
@ -154,11 +154,12 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
// Add the "discovered" field to java.lang.ref.Reference if
|
||||
// it does not exist.
|
||||
void java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
|
||||
constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS);
|
||||
constantPoolHandle cp,
|
||||
FieldAllocationCount *fac_ptr, TRAPS);
|
||||
// Adjust the field allocation counts for java.lang.Class to add
|
||||
// fake fields.
|
||||
void java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
|
||||
FieldAllocationCount *fac_ptr, TRAPS);
|
||||
void java_lang_Class_fix_pre(int* nonstatic_field_size,
|
||||
FieldAllocationCount *fac_ptr);
|
||||
// Adjust the next_nonstatic_oop_offset to place the fake fields
|
||||
// before any Java fields.
|
||||
void java_lang_Class_fix_post(int* next_nonstatic_oop_offset);
|
||||
@ -230,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()
|
||||
@ -257,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());
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.inline.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/instanceMirrorKlass.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/klassOop.hpp"
|
||||
#include "oops/methodOop.hpp"
|
||||
@ -161,7 +162,7 @@ Handle java_lang_String::create_from_unicode(jchar* unicode, int length, TRAPS)
|
||||
}
|
||||
|
||||
Handle java_lang_String::create_tenured_from_unicode(jchar* unicode, int length, TRAPS) {
|
||||
return basic_create_from_unicode(unicode, length, true, CHECK_NH);
|
||||
return basic_create_from_unicode(unicode, length, JavaObjectsInPerm, CHECK_NH);
|
||||
}
|
||||
|
||||
oop java_lang_String::create_oop_from_unicode(jchar* unicode, int length, TRAPS) {
|
||||
@ -300,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);
|
||||
@ -391,6 +401,75 @@ void java_lang_String::print(Handle java_string, outputStream* st) {
|
||||
}
|
||||
}
|
||||
|
||||
static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
|
||||
Handle mirror (THREAD, fd->field_holder()->java_mirror());
|
||||
assert(mirror.not_null() && fd->is_static(), "just checking");
|
||||
if (fd->has_initial_value()) {
|
||||
BasicType t = fd->field_type();
|
||||
switch (t) {
|
||||
case T_BYTE:
|
||||
mirror()->byte_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_BOOLEAN:
|
||||
mirror()->bool_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_CHAR:
|
||||
mirror()->char_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_SHORT:
|
||||
mirror()->short_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_INT:
|
||||
mirror()->int_field_put(fd->offset(), fd->int_initial_value());
|
||||
break;
|
||||
case T_FLOAT:
|
||||
mirror()->float_field_put(fd->offset(), fd->float_initial_value());
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
mirror()->double_field_put(fd->offset(), fd->double_initial_value());
|
||||
break;
|
||||
case T_LONG:
|
||||
mirror()->long_field_put(fd->offset(), fd->long_initial_value());
|
||||
break;
|
||||
case T_OBJECT:
|
||||
{
|
||||
#ifdef ASSERT
|
||||
TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK);
|
||||
assert(fd->signature() == sym, "just checking");
|
||||
#endif
|
||||
oop string = fd->string_initial_value(CHECK);
|
||||
mirror()->obj_field_put(fd->offset(), string);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
THROW_MSG(vmSymbols::java_lang_ClassFormatError(),
|
||||
"Illegal ConstantValue attribute in class file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// During bootstrap, java.lang.Class wasn't loaded so static field
|
||||
// offsets were computed without the size added it. Go back and
|
||||
// update all the static field offsets to included the size.
|
||||
static void fixup_static_field(fieldDescriptor* fd, TRAPS) {
|
||||
if (fd->is_static()) {
|
||||
int real_offset = fd->offset() + instanceMirrorKlass::offset_of_static_fields();
|
||||
typeArrayOop fields = instanceKlass::cast(fd->field_holder())->fields();
|
||||
fields->short_at_put(fd->index() + instanceKlass::low_offset, extract_low_short_from_int(real_offset));
|
||||
fields->short_at_put(fd->index() + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
|
||||
}
|
||||
}
|
||||
|
||||
void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
|
||||
assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already");
|
||||
|
||||
if (k->oop_is_instance()) {
|
||||
// Fixup the offsets
|
||||
instanceKlass::cast(k())->do_local_static_fields(&fixup_static_field, CHECK);
|
||||
}
|
||||
create_mirror(k, CHECK);
|
||||
}
|
||||
|
||||
oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
||||
assert(k->java_mirror() == NULL, "should only assign mirror once");
|
||||
@ -400,12 +479,17 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
||||
// class is put into the system dictionary.
|
||||
int computed_modifiers = k->compute_modifier_flags(CHECK_0);
|
||||
k->set_modifier_flags(computed_modifiers);
|
||||
if (SystemDictionary::Class_klass_loaded()) {
|
||||
if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) {
|
||||
// Allocate mirror (java.lang.Class instance)
|
||||
Handle mirror = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0);
|
||||
Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
|
||||
// Setup indirections
|
||||
mirror->obj_field_put(klass_offset, k());
|
||||
k->set_java_mirror(mirror());
|
||||
|
||||
instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass());
|
||||
java_lang_Class::set_oop_size(mirror(), mk->instance_size(k));
|
||||
java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
|
||||
|
||||
// It might also have a component mirror. This mirror must already exist.
|
||||
if (k->oop_is_javaArray()) {
|
||||
Handle comp_mirror;
|
||||
@ -428,6 +512,9 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
||||
arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror());
|
||||
set_array_klass(comp_mirror(), k->as_klassOop());
|
||||
}
|
||||
} else if (k->oop_is_instance()) {
|
||||
// Initialize static fields
|
||||
instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
|
||||
}
|
||||
return mirror();
|
||||
} else {
|
||||
@ -436,21 +523,46 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
int java_lang_Class::oop_size(oop java_class) {
|
||||
assert(oop_size_offset != 0, "must be set");
|
||||
return java_class->int_field(oop_size_offset);
|
||||
}
|
||||
void java_lang_Class::set_oop_size(oop java_class, int size) {
|
||||
assert(oop_size_offset != 0, "must be set");
|
||||
java_class->int_field_put(oop_size_offset, size);
|
||||
}
|
||||
int java_lang_Class::static_oop_field_count(oop java_class) {
|
||||
assert(static_oop_field_count_offset != 0, "must be set");
|
||||
return java_class->int_field(static_oop_field_count_offset);
|
||||
}
|
||||
void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
|
||||
assert(static_oop_field_count_offset != 0, "must be set");
|
||||
java_class->int_field_put(static_oop_field_count_offset, size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
|
||||
// This should be improved by adding a field at the Java level or by
|
||||
// introducing a new VM klass (see comment in ClassFileParser)
|
||||
oop java_class = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0);
|
||||
oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0);
|
||||
if (type != T_VOID) {
|
||||
klassOop aklass = Universe::typeArrayKlassObj(type);
|
||||
assert(aklass != NULL, "correct bootstrap");
|
||||
set_array_klass(java_class, aklass);
|
||||
}
|
||||
instanceMirrorKlass* mk = instanceMirrorKlass::cast(SystemDictionary::Class_klass());
|
||||
java_lang_Class::set_oop_size(java_class, mk->instance_size(oop(NULL)));
|
||||
java_lang_Class::set_static_oop_field_count(java_class, 0);
|
||||
return java_class;
|
||||
}
|
||||
|
||||
|
||||
klassOop java_lang_Class::as_klassOop(oop java_class) {
|
||||
//%note memory_2
|
||||
assert(java_lang_Class::is_instance(java_class), "must be a Class object");
|
||||
klassOop k = klassOop(java_class->obj_field(klass_offset));
|
||||
assert(k == NULL || k->is_klass(), "type check");
|
||||
return k;
|
||||
@ -2152,7 +2264,7 @@ void java_lang_boxing_object::print(BasicType type, jvalue* value, outputStream*
|
||||
// Support for java_lang_ref_Reference
|
||||
oop java_lang_ref_Reference::pending_list_lock() {
|
||||
instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
|
||||
char *addr = (((char *)ik->start_of_static_fields()) + static_lock_offset);
|
||||
address addr = ik->static_field_addr(static_lock_offset);
|
||||
if (UseCompressedOops) {
|
||||
return oopDesc::load_decode_heap_oop((narrowOop *)addr);
|
||||
} else {
|
||||
@ -2162,7 +2274,7 @@ oop java_lang_ref_Reference::pending_list_lock() {
|
||||
|
||||
HeapWord *java_lang_ref_Reference::pending_list_addr() {
|
||||
instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
|
||||
char *addr = (((char *)ik->start_of_static_fields()) + static_pending_offset);
|
||||
address addr = ik->static_field_addr(static_pending_offset);
|
||||
// XXX This might not be HeapWord aligned, almost rather be char *.
|
||||
return (HeapWord*)addr;
|
||||
}
|
||||
@ -2185,16 +2297,14 @@ jlong java_lang_ref_SoftReference::timestamp(oop ref) {
|
||||
|
||||
jlong java_lang_ref_SoftReference::clock() {
|
||||
instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
|
||||
int offset = ik->offset_of_static_fields() + static_clock_offset;
|
||||
|
||||
return SystemDictionary::SoftReference_klass()->long_field(offset);
|
||||
jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
|
||||
return *offset;
|
||||
}
|
||||
|
||||
void java_lang_ref_SoftReference::set_clock(jlong value) {
|
||||
instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
|
||||
int offset = ik->offset_of_static_fields() + static_clock_offset;
|
||||
|
||||
SystemDictionary::SoftReference_klass()->long_field_put(offset, value);
|
||||
jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
|
||||
*offset = value;
|
||||
}
|
||||
|
||||
|
||||
@ -2221,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);
|
||||
@ -2236,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());
|
||||
@ -2248,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);
|
||||
}
|
||||
@ -2263,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);
|
||||
}
|
||||
}
|
||||
@ -2625,26 +2735,18 @@ oop java_lang_ClassLoader::non_reflection_class_loader(oop loader) {
|
||||
|
||||
|
||||
// Support for java_lang_System
|
||||
|
||||
void java_lang_System::compute_offsets() {
|
||||
assert(offset_of_static_fields == 0, "offsets should be initialized only once");
|
||||
|
||||
instanceKlass* ik = instanceKlass::cast(SystemDictionary::System_klass());
|
||||
offset_of_static_fields = ik->offset_of_static_fields();
|
||||
}
|
||||
|
||||
int java_lang_System::in_offset_in_bytes() {
|
||||
return (offset_of_static_fields + static_in_offset);
|
||||
return (instanceMirrorKlass::offset_of_static_fields() + static_in_offset);
|
||||
}
|
||||
|
||||
|
||||
int java_lang_System::out_offset_in_bytes() {
|
||||
return (offset_of_static_fields + static_out_offset);
|
||||
return (instanceMirrorKlass::offset_of_static_fields() + static_out_offset);
|
||||
}
|
||||
|
||||
|
||||
int java_lang_System::err_offset_in_bytes() {
|
||||
return (offset_of_static_fields + static_err_offset);
|
||||
return (instanceMirrorKlass::offset_of_static_fields() + static_err_offset);
|
||||
}
|
||||
|
||||
|
||||
@ -2657,6 +2759,8 @@ int java_lang_Class::klass_offset;
|
||||
int java_lang_Class::array_klass_offset;
|
||||
int java_lang_Class::resolved_constructor_offset;
|
||||
int java_lang_Class::number_of_fake_oop_fields;
|
||||
int java_lang_Class::oop_size_offset;
|
||||
int java_lang_Class::static_oop_field_count_offset;
|
||||
int java_lang_Throwable::backtrace_offset;
|
||||
int java_lang_Throwable::detailMessage_offset;
|
||||
int java_lang_Throwable::cause_offset;
|
||||
@ -2700,7 +2804,6 @@ int java_lang_ref_Reference::number_of_fake_oop_fields;
|
||||
int java_lang_ref_SoftReference::timestamp_offset;
|
||||
int java_lang_ref_SoftReference::static_clock_offset;
|
||||
int java_lang_ClassLoader::parent_offset;
|
||||
int java_lang_System::offset_of_static_fields;
|
||||
int java_lang_System::static_in_offset;
|
||||
int java_lang_System::static_out_offset;
|
||||
int java_lang_System::static_err_offset;
|
||||
@ -2817,10 +2920,19 @@ void JavaClasses::compute_hard_coded_offsets() {
|
||||
java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint);
|
||||
java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint);
|
||||
|
||||
// Do the Class Class
|
||||
java_lang_Class::klass_offset = java_lang_Class::hc_klass_offset * x + header;
|
||||
java_lang_Class::array_klass_offset = java_lang_Class::hc_array_klass_offset * x + header;
|
||||
java_lang_Class::resolved_constructor_offset = java_lang_Class::hc_resolved_constructor_offset * x + header;
|
||||
{
|
||||
// Do the Class Class
|
||||
int offset = header;
|
||||
java_lang_Class::oop_size_offset = header;
|
||||
offset += BytesPerInt;
|
||||
java_lang_Class::static_oop_field_count_offset = offset;
|
||||
offset = align_size_up(offset + BytesPerInt, x);
|
||||
java_lang_Class::klass_offset = offset;
|
||||
offset += x;
|
||||
java_lang_Class::array_klass_offset = offset;
|
||||
offset += x;
|
||||
java_lang_Class::resolved_constructor_offset = offset;
|
||||
}
|
||||
|
||||
// This is NOT an offset
|
||||
java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields;
|
||||
@ -2877,10 +2989,9 @@ void JavaClasses::compute_hard_coded_offsets() {
|
||||
void JavaClasses::compute_offsets() {
|
||||
|
||||
java_lang_Class::compute_offsets();
|
||||
java_lang_System::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();
|
||||
@ -2888,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();
|
||||
@ -2961,10 +3070,10 @@ bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offs
|
||||
tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name);
|
||||
return false;
|
||||
}
|
||||
if (fd.offset() == hardcoded_offset + h_klass->offset_of_static_fields()) {
|
||||
if (fd.offset() == hardcoded_offset + instanceMirrorKlass::offset_of_static_fields()) {
|
||||
return true;
|
||||
} else {
|
||||
tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - h_klass->offset_of_static_fields());
|
||||
tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - instanceMirrorKlass::offset_of_static_fields());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -138,10 +162,8 @@ class java_lang_Class : AllStatic {
|
||||
// The fake offsets are added by the class loader when java.lang.Class is loaded
|
||||
|
||||
enum {
|
||||
hc_klass_offset = 0,
|
||||
hc_array_klass_offset = 1,
|
||||
hc_resolved_constructor_offset = 2,
|
||||
hc_number_of_fake_oop_fields = 3
|
||||
hc_number_of_fake_oop_fields = 3,
|
||||
hc_number_of_fake_int_fields = 2
|
||||
};
|
||||
|
||||
static int klass_offset;
|
||||
@ -149,6 +171,9 @@ class java_lang_Class : AllStatic {
|
||||
static int array_klass_offset;
|
||||
static int number_of_fake_oop_fields;
|
||||
|
||||
static int oop_size_offset;
|
||||
static int static_oop_field_count_offset;
|
||||
|
||||
static void compute_offsets();
|
||||
static bool offsets_computed;
|
||||
static int classRedefinedCount_offset;
|
||||
@ -157,6 +182,7 @@ class java_lang_Class : AllStatic {
|
||||
public:
|
||||
// Instance creation
|
||||
static oop create_mirror(KlassHandle k, TRAPS);
|
||||
static void fixup_mirror(KlassHandle k, TRAPS);
|
||||
static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
|
||||
// Conversion
|
||||
static klassOop as_klassOop(oop java_class);
|
||||
@ -191,6 +217,12 @@ class java_lang_Class : AllStatic {
|
||||
static void set_classRedefinedCount(oop the_class_mirror, int value);
|
||||
// Support for parallelCapable field
|
||||
static bool parallelCapable(oop the_class_mirror);
|
||||
|
||||
static int oop_size(oop java_class);
|
||||
static void set_oop_size(oop java_class, int size);
|
||||
static int static_oop_field_count(oop java_class);
|
||||
static void set_static_oop_field_count(oop java_class, int size);
|
||||
|
||||
// Debugging
|
||||
friend class JavaClasses;
|
||||
friend class instanceKlass; // verification code accesses offsets
|
||||
@ -1165,13 +1197,10 @@ class java_lang_System : AllStatic {
|
||||
hc_static_err_offset = 2
|
||||
};
|
||||
|
||||
static int offset_of_static_fields;
|
||||
static int static_in_offset;
|
||||
static int static_out_offset;
|
||||
static int static_err_offset;
|
||||
|
||||
static void compute_offsets();
|
||||
|
||||
public:
|
||||
static int in_offset_in_bytes();
|
||||
static int out_offset_in_bytes();
|
||||
|
@ -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,
|
||||
@ -530,7 +503,7 @@ oop StringTable::basic_add(int index, Handle string_or_null, jchar* name,
|
||||
|
||||
Handle string;
|
||||
// try to reuse the string if possible
|
||||
if (!string_or_null.is_null() && string_or_null()->is_perm()) {
|
||||
if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) {
|
||||
string = string_or_null;
|
||||
} else {
|
||||
string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
|
||||
@ -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);
|
||||
|
||||
@ -662,11 +635,8 @@ void StringTable::verify() {
|
||||
for ( ; p != NULL; p = p->next()) {
|
||||
oop s = p->literal();
|
||||
guarantee(s != NULL, "interned string is NULL");
|
||||
guarantee(s->is_perm(), "interned string not in permspace");
|
||||
|
||||
int length;
|
||||
jchar* chars = java_lang_String::as_unicode_string(s, length);
|
||||
unsigned int h = hash_string(chars, length);
|
||||
guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
|
||||
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
|
||||
@ -216,18 +216,14 @@ private:
|
||||
oop basic_add(int index, Handle string_or_null, jchar* name, int len,
|
||||
unsigned int hashValue, TRAPS);
|
||||
|
||||
// Table size
|
||||
enum {
|
||||
string_table_size = 1009
|
||||
};
|
||||
|
||||
oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
|
||||
|
||||
StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {}
|
||||
StringTable() : Hashtable<oop>((int)StringTableSize,
|
||||
sizeof (HashtableEntry<oop>)) {}
|
||||
|
||||
StringTable(HashtableBucket* t, int number_of_entries)
|
||||
: Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t,
|
||||
number_of_entries) {}
|
||||
: Hashtable<oop>((int)StringTableSize, sizeof (HashtableEntry<oop>), t,
|
||||
number_of_entries) {}
|
||||
|
||||
public:
|
||||
// The string table
|
||||
@ -241,13 +237,11 @@ public:
|
||||
static void create_table(HashtableBucket* t, int length,
|
||||
int number_of_entries) {
|
||||
assert(_the_table == NULL, "One string table allowed.");
|
||||
assert(length == string_table_size * sizeof(HashtableBucket),
|
||||
assert((size_t)length == StringTableSize * sizeof(HashtableBucket),
|
||||
"bad shared string size.");
|
||||
_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.
|
||||
|
@ -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
|
||||
@ -337,7 +337,6 @@ void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
|
||||
if (is_live) {
|
||||
// Perform cur->oops_do(f), maybe just once per nmethod.
|
||||
f->do_code_blob(cur);
|
||||
cur->fix_oop_relocations();
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,6 +551,19 @@ void CodeCache::gc_epilogue() {
|
||||
}
|
||||
|
||||
|
||||
void CodeCache::verify_oops() {
|
||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
VerifyOopClosure voc;
|
||||
FOR_ALL_ALIVE_BLOBS(cb) {
|
||||
if (cb->is_nmethod()) {
|
||||
nmethod *nm = (nmethod*)cb;
|
||||
nm->oops_do(&voc);
|
||||
nm->verify_oop_relocations();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
address CodeCache::first_address() {
|
||||
assert_locked_or_safepoint(CodeCache_lock);
|
||||
return (address)_heap->begin();
|
||||
|
@ -122,6 +122,7 @@ class CodeCache : AllStatic {
|
||||
// GC support
|
||||
static void gc_epilogue();
|
||||
static void gc_prologue();
|
||||
static void verify_oops();
|
||||
// If "unloading_occurred" is true, then unloads (i.e., breaks root links
|
||||
// to) any unmarked codeBlobs in the cache. Sets "marked_for_unloading"
|
||||
// to "true" iff some code got unloaded.
|
||||
|
@ -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);
|
||||
@ -653,6 +656,9 @@ nmethod::nmethod(
|
||||
_pc_desc_cache.reset_to(NULL);
|
||||
|
||||
code_buffer->copy_oops_to(this);
|
||||
if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
|
||||
CodeCache::add_scavenge_root_nmethod(this);
|
||||
}
|
||||
debug_only(verify_scavenge_root_oops());
|
||||
CodeCache::commit(this);
|
||||
}
|
||||
@ -927,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);
|
||||
}
|
||||
}
|
||||
@ -1105,6 +1050,20 @@ void nmethod::fix_oop_relocations(address begin, address end, bool initialize_im
|
||||
}
|
||||
|
||||
|
||||
void nmethod::verify_oop_relocations() {
|
||||
// Ensure sure that the code matches the current oop values
|
||||
RelocIterator iter(this, NULL, NULL);
|
||||
while (iter.next()) {
|
||||
if (iter.type() == relocInfo::oop_type) {
|
||||
oop_Relocation* reloc = iter.oop_reloc();
|
||||
if (!reloc->oop_is_immediate()) {
|
||||
reloc->verify_oop_relocation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ScopeDesc* nmethod::scope_desc_at(address pc) {
|
||||
PcDesc* pd = pc_desc_at(pc);
|
||||
guarantee(pd != NULL, "scope must be present");
|
||||
@ -1292,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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1799,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;
|
||||
}
|
||||
}
|
||||
@ -1823,7 +1781,8 @@ void nmethod::oops_do_marking_epilogue() {
|
||||
assert(cur != NULL, "not NULL-terminated");
|
||||
nmethod* next = cur->_oops_do_mark_link;
|
||||
cur->_oops_do_mark_link = NULL;
|
||||
NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark\n"));
|
||||
cur->fix_oop_relocations();
|
||||
NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark"));
|
||||
cur = next;
|
||||
}
|
||||
void* required = _oops_do_mark_nmethods;
|
||||
@ -2378,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) ");
|
||||
@ -2390,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());
|
||||
@ -2778,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,
|
||||
@ -459,6 +461,7 @@ private:
|
||||
public:
|
||||
void fix_oop_relocations(address begin, address end) { fix_oop_relocations(begin, end, false); }
|
||||
void fix_oop_relocations() { fix_oop_relocations(NULL, NULL, false); }
|
||||
void verify_oop_relocations();
|
||||
|
||||
bool is_at_poll_return(address pc);
|
||||
bool is_at_poll_or_poll_return(address pc);
|
||||
@ -499,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; }
|
||||
@ -607,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();
|
||||
@ -626,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;
|
||||
|
@ -798,6 +798,14 @@ void oop_Relocation::fix_oop_relocation() {
|
||||
}
|
||||
|
||||
|
||||
void oop_Relocation::verify_oop_relocation() {
|
||||
if (!oop_is_immediate()) {
|
||||
// get the oop from the pool, and re-insert it into the instruction:
|
||||
verify_value(value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
|
||||
oop* &oop_addr, bool *is_optimized) {
|
||||
assert(ic_call != NULL, "ic_call address must be set");
|
||||
|
@ -765,7 +765,8 @@ class Relocation VALUE_OBJ_CLASS_SPEC {
|
||||
|
||||
protected:
|
||||
// platform-dependent utilities for decoding and patching instructions
|
||||
void pd_set_data_value (address x, intptr_t off); // a set or mem-ref
|
||||
void pd_set_data_value (address x, intptr_t off, bool verify_only = false); // a set or mem-ref
|
||||
void pd_verify_data_value (address x, intptr_t off) { pd_set_data_value(x, off, true); }
|
||||
address pd_call_destination (address orig_addr = NULL);
|
||||
void pd_set_call_destination (address x);
|
||||
void pd_swap_in_breakpoint (address x, short* instrs, int instrlen);
|
||||
@ -880,6 +881,12 @@ class DataRelocation : public Relocation {
|
||||
else
|
||||
pd_set_data_value(x, o);
|
||||
}
|
||||
void verify_value(address x) {
|
||||
if (addr_in_const())
|
||||
assert(*(address*)addr() == x, "must agree");
|
||||
else
|
||||
pd_verify_data_value(x, offset());
|
||||
}
|
||||
|
||||
// The "o" (displacement) argument is relevant only to split relocations
|
||||
// on RISC machines. In some CPUs (SPARC), the set-hi and set-lo ins'ns
|
||||
@ -950,6 +957,8 @@ class oop_Relocation : public DataRelocation {
|
||||
|
||||
void fix_oop_relocation(); // reasserts oop value
|
||||
|
||||
void verify_oop_relocation();
|
||||
|
||||
address value() { return (address) *oop_addr(); }
|
||||
|
||||
bool oop_is_immediate() { return oop_index() == 0; }
|
||||
|
@ -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);
|
||||
|
@ -5930,14 +5930,18 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
|
||||
}
|
||||
|
||||
{
|
||||
TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
|
||||
// Now clean up stale oops in StringTable
|
||||
StringTable::unlink(&_is_alive_closure);
|
||||
TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
|
||||
// Clean up unreferenced symbols in symbol table.
|
||||
SymbolTable::unlink();
|
||||
}
|
||||
}
|
||||
|
||||
if (should_unload_classes() || !JavaObjectsInPerm) {
|
||||
TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
|
||||
// Now clean up stale oops in StringTable
|
||||
StringTable::unlink(&_is_alive_closure);
|
||||
}
|
||||
|
||||
verify_work_stacks_empty();
|
||||
// Restore any preserved marks as a result of mark stack or
|
||||
// work queue overflow
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
|
||||
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
|
||||
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
||||
@ -439,6 +440,14 @@ bool PSScavenge::invoke_no_policy() {
|
||||
reference_processor()->enqueue_discovered_references(NULL);
|
||||
}
|
||||
|
||||
if (!JavaObjectsInPerm) {
|
||||
// Unlink any dead interned Strings
|
||||
StringTable::unlink(&_is_alive_closure);
|
||||
// Process the remaining live ones
|
||||
PSScavengeRootsClosure root_closure(promotion_manager);
|
||||
StringTable::oops_do(&root_closure);
|
||||
}
|
||||
|
||||
// Finally, flush the promotion_manager's labs, and deallocate its stacks.
|
||||
PSPromotionManager::post_scavenge();
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user