This commit is contained in:
Lana Steuck 2011-03-31 22:08:44 -07:00
commit a37420e027
476 changed files with 30925 additions and 8992 deletions
.hgtags.hgtags-top-repoREADME-builds.html
corba
hotspot
.hgtags
agent
make
src

@ -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");
}
}

@ -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