# HG changeset patch # User Doug Simon # Date 1367842448 -7200 # Node ID df3aa336a313090608c3e8d532cf3be2c27869cf # Parent a79e8020ad4b220313d3904daf793c22367da329 replaced verify_oop assembler stub with a compiled stub (GRAAL-81) diff -r a79e8020ad4b -r df3aa336a313 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Mon May 06 13:49:20 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Mon May 06 14:14:08 2013 +0200 @@ -28,7 +28,6 @@ import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; -import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*; import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*; import static com.oracle.graal.hotspot.nodes.WriteBarrierPreStubCall.*; import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.DecryptBlockStubCall.*; @@ -101,11 +100,6 @@ /* arg0: object */ javaCallingConvention(Kind.Object, /* arg1: lock */ word)); - addRuntimeCall(VERIFY_OOP, config.verifyOopStub, - /* temps */ null, - /* ret */ ret(Kind.Void), - /* arg0: object */ r13.asValue(Kind.Object)); - addRuntimeCall(VM_ERROR, config.vmErrorStub, /* temps */ null, /* ret */ ret(Kind.Void), diff -r a79e8020ad4b -r df3aa336a313 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon May 06 13:49:20 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon May 06 14:14:08 2013 +0200 @@ -240,6 +240,10 @@ */ public int threadIsMethodHandleReturnOffset; + public long verifyOopCounterAddress; + public long verifyOopMask; + public long verifyOopBits; + /** * Offset of the _exception_oop field in Thread (defined in thread.hpp). This field is used to * pass exception objects into and out of the runtime system during exception handling for @@ -370,7 +374,6 @@ public long wbPreCallStub; public long wbPostCallStub; - public long verifyOopStub; public long vmErrorStub; public long uncommonTrapStub; public long unwindExceptionStub; diff -r a79e8020ad4b -r df3aa336a313 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon May 06 13:49:20 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon May 06 14:14:08 2013 +0200 @@ -35,6 +35,7 @@ import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*; import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*; import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*; +import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*; import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*; import static com.oracle.graal.hotspot.stubs.IdentityHashCodeStub.*; @@ -217,6 +218,10 @@ // @formatter:off + addStubCall(VERIFY_OOP, + /* ret */ ret(Kind.Object), + /* arg0: object */ javaCallingConvention(Kind.Object)); + addRuntimeCall(OSR_MIGRATION_END, config.osrMigrationEndStub, /* temps */ null, /* ret */ ret(Kind.Void), @@ -487,6 +492,7 @@ registerStub(new IdentityHashCodeStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(IDENTITY_HASHCODE))); registerStub(new ExceptionHandlerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(EXCEPTION_HANDLER))); registerStub(new UnwindExceptionToCallerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(UNWIND_EXCEPTION_TO_CALLER))); + registerStub(new VerifyOopStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(VERIFY_OOP))); } private void registerStub(Stub stub) { diff -r a79e8020ad4b -r df3aa336a313 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Mon May 06 13:49:20 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Mon May 06 14:14:08 2013 +0200 @@ -26,16 +26,17 @@ import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; /** - * Node implementing a call to HotSpot's object pointer verification stub. + * Call to {@link VerifyOopStub}. */ public class VerifyOopStubCall extends DeoptimizingStubCall implements LIRGenLowerable { @Input private final ValueNode object; - public static final Descriptor VERIFY_OOP = new Descriptor("verify_oop", false, void.class, Object.class); + public static final Descriptor VERIFY_OOP = new Descriptor("verify_oop", false, Object.class, Object.class); public VerifyOopStubCall(ValueNode object) { super(StampFactory.objectNonNull()); diff -r a79e8020ad4b -r df3aa336a313 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Mon May 06 13:49:20 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Mon May 06 14:14:08 2013 +0200 @@ -28,6 +28,7 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.nodes.CStringNode.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.word.Word.*; import java.lang.reflect.*; import java.util.*; @@ -54,7 +55,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.replacements.*; -import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.Snippet.*; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; @@ -360,4 +361,49 @@ public static void fatal(String format, long v1, long v2, long v3) { vmMessageC(VM_MESSAGE_C, true, cstring(format), v1, v2, v3); } + + /** + * Verifies that a given object value is well formed if {@code -XX:+VerifyOops} is enabled. + */ + public static Object verifyObject(Object object) { + if (verifyOops()) { + // TODO (ds) The counter read is ok but the write causes a segv - find out why + // Word verifyOopCounter = Word.unsigned(verifyOopCounterAddress()); + // verifyOopCounter.writeInt(0, verifyOopCounter.readInt(0) + 1); + + Pointer oop = Word.fromObject(object); + if (object != null) { + // make sure object is 'reasonable' + if (!oop.and(unsigned(verifyOopMask())).equal(unsigned(verifyOopBits()))) { + fatal("oop not in heap: %p", oop.rawValue()); + } + + Word klass = oop.readWord(hubOffset()); + if (klass.equal(Word.zero())) { + fatal("klass for oop %p is null", oop.rawValue()); + } + } + } + return object; + } + + @Fold + private static long verifyOopCounterAddress() { + return config().verifyOopCounterAddress; + } + + @Fold + private static long verifyOopMask() { + return config().verifyOopMask; + } + + @Fold + private static long verifyOopBits() { + return config().verifyOopBits; + } + + @Fold + private static int hubOffset() { + return config().hubOffset; + } } diff -r a79e8020ad4b -r df3aa336a313 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Mon May 06 14:14:08 2013 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, 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 com.oracle.graal.hotspot.stubs; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.*; + +/** + * Stub called from {@link VerifyOopStubCall}. + */ +public class VerifyOopStub extends CRuntimeStub { + + public VerifyOopStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) { + super(runtime, replacements, target, linkage); + } + + @Snippet + private static Object verifyOop(Object object) { + return verifyObject(object); + } +} diff -r a79e8020ad4b -r df3aa336a313 src/cpu/x86/vm/graalRuntime_x86.cpp --- a/src/cpu/x86/vm/graalRuntime_x86.cpp Mon May 06 13:49:20 2013 +0200 +++ b/src/cpu/x86/vm/graalRuntime_x86.cpp Mon May 06 14:14:08 2013 +0200 @@ -708,15 +708,6 @@ break; } - case verify_oop_id: { - // We use enter & leave so that a better stack trace is produced in the hs_err file - __ enter(); - __ verify_oop(r13, "Graal verify oop"); - __ leave(); - __ ret(0); - break; - } - case arithmetic_frem_id: { __ subptr(rsp, 8); __ movflt(Address(rsp, 0), xmm1); diff -r a79e8020ad4b -r df3aa336a313 src/cpu/x86/vm/graalStubAssembler_x86.cpp --- a/src/cpu/x86/vm/graalStubAssembler_x86.cpp Mon May 06 13:49:20 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1999, 2012, 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. - * - */ - -#include "precompiled.hpp" -#include "graal/graalRuntime.hpp" -#include "classfile/systemDictionary.hpp" -#include "gc_interface/collectedHeap.hpp" -#include "interpreter/interpreter.hpp" -#include "oops/arrayOop.hpp" -#include "oops/markOop.hpp" -#include "runtime/basicLock.hpp" -#include "runtime/biasedLocking.hpp" -#include "runtime/os.hpp" -#include "runtime/stubRoutines.hpp" - -#ifndef PRODUCT - -void GraalStubAssembler::verify_stack_oop(int stack_offset) { - if (!VerifyOops) return; - verify_oop_addr(Address(rsp, stack_offset)); -} - -void GraalStubAssembler::verify_not_null_oop(Register r) { - if (!VerifyOops) return; - Label not_null; - testptr(r, r); - jcc(Assembler::notZero, not_null); - stop("non-null oop required"); - bind(not_null); - verify_oop(r); -} - -#endif // ifndef PRODUCT diff -r a79e8020ad4b -r df3aa336a313 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon May 06 13:49:20 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon May 06 14:14:08 2013 +0200 @@ -741,6 +741,10 @@ set_boolean("tlabStats", TLABStats); set_boolean("inlineContiguousAllocationSupported", !CMSIncrementalMode && Universe::heap()->supports_inline_contig_alloc()); + set_long("verifyOopCounterAddress", (jlong)(address) StubRoutines::verify_oop_count_addr); + set_long("verifyOopMask", Universe::verify_oop_mask()); + set_long("verifyOopBits", Universe::verify_oop_bits()); + set_long("arrayPrototypeMarkWord", (intptr_t)markOopDesc::prototype()); set_int("layoutHelperLog2ElementSizeShift", Klass::_lh_log2_element_size_shift); set_int("layoutHelperLog2ElementSizeMask", Klass::_lh_log2_element_size_mask); @@ -760,7 +764,6 @@ set_address("handleDeoptStub", SharedRuntime::deopt_blob()->unpack()); set_address("monitorEnterStub", GraalRuntime::entry_for(GraalRuntime::monitorenter_id)); set_address("monitorExitStub", GraalRuntime::entry_for(GraalRuntime::monitorexit_id)); - set_address("verifyOopStub", GraalRuntime::entry_for(GraalRuntime::verify_oop_id)); set_address("vmErrorStub", GraalRuntime::entry_for(GraalRuntime::vm_error_id)); set_address("osrMigrationEndStub", GraalRuntime::entry_for(GraalRuntime::OSR_migration_end_id)); set_address("createNullPointerExceptionStub", GraalRuntime::entry_for(GraalRuntime::create_null_pointer_exception_id)); diff -r a79e8020ad4b -r df3aa336a313 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Mon May 06 13:49:20 2013 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Mon May 06 14:14:08 2013 +0200 @@ -127,10 +127,6 @@ // Make sure that stubs that need oopmaps have them switch (id) { // These stubs don't need to have an oopmap -#if defined(SPARC) || defined(PPC) - case handle_exception_nofpu_id: // Unused on sparc -#endif - case verify_oop_id: case OSR_migration_end_id: case arithmetic_frem_id: case arithmetic_drem_id: diff -r a79e8020ad4b -r df3aa336a313 src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Mon May 06 13:49:20 2013 +0200 +++ b/src/share/vm/graal/graalRuntime.hpp Mon May 06 14:14:08 2013 +0200 @@ -62,9 +62,6 @@ int num_rt_args() const { return _num_rt_args; } int stub_id() const { return _stub_id; } - void verify_stack_oop(int offset) PRODUCT_RETURN; - void verify_not_null_oop(Register r) PRODUCT_RETURN; - // runtime calls (return offset of call to be used by GC map) int call_RT(Register oop_result1, Register metadata_result, address entry, int args_size = 0); int call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1); @@ -86,7 +83,6 @@ stub(arithmetic_drem) \ stub(monitorenter) \ stub(monitorexit) \ - stub(verify_oop) \ stub(vm_error) \ stub(create_null_pointer_exception) \ stub(create_out_of_bounds_exception) \