changeset 5251:467de393651a

optimization: frame prologue & epilogue ommitted for methods with no spills, no callee-saved registers, no incoming stack args and no debug info
author Doug Simon <doug.simon@oracle.com>
date Wed, 18 Apr 2012 23:39:07 +0200
parents 0f6f647e8a96
children 1a9a048386d6 9fe76535501f
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/FrameContext.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java src/share/vm/code/nmethod.cpp src/share/vm/code/nmethod.hpp src/share/vm/graal/graalEnv.cpp
diffstat 13 files changed, 152 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Apr 18 23:39:07 2012 +0200
@@ -276,8 +276,7 @@
             targetMethod.setAssumptions(assumptions);
         }
 
-        Debug.dump(lir, "After code generation");
-        Debug.dump(targetMethod, "Generated code");
+        Debug.dump(targetMethod, "After code generation");
         return targetMethod;
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Apr 18 23:39:07 2012 +0200
@@ -490,7 +490,14 @@
         CiValue[] params = new CiValue[incomingArguments.locations.length];
         for (int i = 0; i < params.length; i++) {
             params[i] = toStackKind(incomingArguments.locations[i]);
+            if (CiValueUtil.isStackSlot(params[i])) {
+                CiStackSlot slot = CiValueUtil.asStackSlot(params[i]);
+                if (slot.inCallerFrame() && !lir.hasArgInCallerFrame()) {
+                    lir.setHasArgInCallerFrame();
+                }
+            }
         }
+
         append(new ParametersOp(params));
 
         for (LocalNode local : graph.getNodes(LocalNode.class)) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Apr 18 23:39:07 2012 +0200
@@ -80,13 +80,13 @@
 
     /**
      * Emits code to do stack overflow checking.
-     *
+     * 
      * @param afterFrameInit specifies if the stack pointer has already been adjusted to allocate the current frame
      */
-    protected static void emitStackOverflowCheck(TargetMethodAssembler tasm, LIR lir, boolean afterFrameInit) {
+    protected static void emitStackOverflowCheck(TargetMethodAssembler tasm, boolean afterFrameInit) {
         if (GraalOptions.StackShadowPages > 0) {
             int frameSize = tasm.frameMap.frameSize();
-            if (frameSize > 0 || lir.containsCalls()) {
+            if (frameSize > 0) {
                 int lastFramePage = frameSize / tasm.target.pageSize;
                 // emit multiple stack bangs for methods with frames larger than a page
                 for (int i = 0; i <= lastFramePage; i++) {
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Wed Apr 18 23:39:07 2012 +0200
@@ -158,6 +158,10 @@
         }
     }
 
+    /**
+     * Searches the current debug scope, bottom up, for a context object that is an instance of a given type.
+     * The first such object found is returned.
+     */
     @SuppressWarnings("unchecked")
     public static <T> T contextLookup(Class<T> clazz) {
         if (ENABLED) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Wed Apr 18 23:39:07 2012 +0200
@@ -42,11 +42,11 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ci.CiCallingConvention.Type;
-import com.oracle.max.cri.ci.CiRegister.*;
+import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
 
@@ -89,45 +89,32 @@
 
     class HotSpotFrameContext implements FrameContext {
 
-        private final LIR lir;
-        private boolean needsLeave;
-
-        public HotSpotFrameContext(LIR lir) {
-            this.lir = lir;
-        }
-
         @Override
         public void enter(TargetMethodAssembler tasm) {
             FrameMap frameMap = tasm.frameMap;
             int frameSize = frameMap.frameSize();
-            if (frameSize != 0) {
-                AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
-                emitStackOverflowCheck(tasm, lir, false);
-                asm.push(rbp);
-                asm.movq(rbp, rsp);
-                asm.decrementq(rsp, frameSize - 8); // account for the push of RBP above
-                if (GraalOptions.ZapStackOnMethodEntry) {
-                    final int intSize = 4;
-                    for (int i = 0; i < frameSize / intSize; ++i) {
-                        asm.movl(new CiAddress(CiKind.Int, rsp.asValue(), i * intSize), 0xC1C1C1C1);
-                    }
+
+            AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
+            emitStackOverflowCheck(tasm, false);
+            asm.push(rbp);
+            asm.movq(rbp, rsp);
+            asm.decrementq(rsp, frameSize - 8); // account for the push of RBP above
+            if (GraalOptions.ZapStackOnMethodEntry) {
+                final int intSize = 4;
+                for (int i = 0; i < frameSize / intSize; ++i) {
+                    asm.movl(new CiAddress(CiKind.Int, rsp.asValue(), i * intSize), 0xC1C1C1C1);
                 }
-                CiCalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout();
-                if (csl != null && csl.size != 0) {
-                    int frameToCSA = frameMap.offsetToCalleeSaveArea();
-                    assert frameToCSA >= 0;
-                    asm.save(csl, frameToCSA);
-                }
-                needsLeave = true;
+            }
+            CiCalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout();
+            if (csl != null && csl.size != 0) {
+                int frameToCSA = frameMap.offsetToCalleeSaveArea();
+                assert frameToCSA >= 0;
+                asm.save(csl, frameToCSA);
             }
         }
 
         @Override
         public void leave(TargetMethodAssembler tasm) {
-            if (!needsLeave) {
-                return;
-            }
-
             int frameSize = tasm.frameMap.frameSize();
             AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
             CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
@@ -165,8 +152,19 @@
 
     @Override
     public TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir) {
+        // Omit the frame if the method:
+        //  - has no spill slots or other slots allocated during register allocation
+        //  - has no callee-saved registers
+        //  - has no incoming arguments passed on the stack
+        //  - has no instructions with debug info
+        boolean canOmitFrame =
+            frameMap.frameSize() == frameMap.initialFrameSize &&
+            frameMap.registerConfig.getCalleeSaveLayout().registers.length == 0 &&
+            !lir.hasArgInCallerFrame() &&
+            !lir.hasDebugInfo();
+
         AbstractAssembler masm = new AMD64MacroAssembler(target, frameMap.registerConfig);
-        HotSpotFrameContext frameContext = new HotSpotFrameContext(lir);
+        HotSpotFrameContext frameContext = canOmitFrame ? null : new HotSpotFrameContext();
         TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime, frameMap, masm, frameContext);
         tasm.setFrameSize(frameMap.frameSize());
         tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
@@ -202,28 +200,34 @@
         // Emit code for the LIR
         lir.emitCode(tasm);
 
-        // Emit the suffix (i.e. out-of-line stubs)
-        CiRegister thread = r15;
-        CiRegister exceptionOop = regConfig.getCallingConventionRegisters(Type.RuntimeCall, RegisterFlag.CPU)[0];
-        Label unwind = new Label();
-        asm.bind(unwind);
-        tasm.recordMark(MARK_UNWIND_ENTRY);
-        CiAddress exceptionOopField = new CiAddress(CiKind.Object, thread.asValue(), config.threadExceptionOopOffset);
-        CiAddress exceptionPcField = new CiAddress(CiKind.Object, thread.asValue(), config.threadExceptionPcOffset);
-        asm.movq(exceptionOop, exceptionOopField);
-        asm.movslq(exceptionOopField, 0);
-        asm.movslq(exceptionPcField, 0);
+        boolean frameOmitted = tasm.frameContext == null;
+        if (!frameOmitted) {
+            CiRegister thread = r15;
+            CiRegister exceptionOop = regConfig.getCallingConventionRegisters(Type.RuntimeCall, RegisterFlag.CPU)[0];
+            Label unwind = new Label();
+            asm.bind(unwind);
+            tasm.recordMark(MARK_UNWIND_ENTRY);
+            CiAddress exceptionOopField = new CiAddress(CiKind.Object, thread.asValue(), config.threadExceptionOopOffset);
+            CiAddress exceptionPcField = new CiAddress(CiKind.Object, thread.asValue(), config.threadExceptionPcOffset);
+            asm.movq(exceptionOop, exceptionOopField);
+            asm.movslq(exceptionOopField, 0);
+            asm.movslq(exceptionPcField, 0);
 
-        AMD64Call.directCall(tasm, asm, config.unwindExceptionStub, null);
-        AMD64Call.shouldNotReachHere(tasm, asm);
+            AMD64Call.directCall(tasm, asm, config.unwindExceptionStub, null);
+            AMD64Call.shouldNotReachHere(tasm, asm);
+
+            tasm.recordMark(MARK_EXCEPTION_HANDLER_ENTRY);
+            AMD64Call.directCall(tasm, asm, config.handleExceptionStub, null);
+            AMD64Call.shouldNotReachHere(tasm, asm);
 
-        tasm.recordMark(MARK_EXCEPTION_HANDLER_ENTRY);
-        AMD64Call.directCall(tasm, asm, config.handleExceptionStub, null);
-        AMD64Call.shouldNotReachHere(tasm, asm);
-
-        tasm.recordMark(MARK_DEOPT_HANDLER_ENTRY);
-        AMD64Call.directCall(tasm, asm, config.handleDeoptStub, null);
-        AMD64Call.shouldNotReachHere(tasm, asm);
+            tasm.recordMark(MARK_DEOPT_HANDLER_ENTRY);
+            AMD64Call.directCall(tasm, asm, config.handleDeoptStub, null);
+            AMD64Call.shouldNotReachHere(tasm, asm);
+        } else {
+            // No need to emit the stubs for entries back into the method since
+            // it has no calls that can cause such "return" entries
+            assert !frameMap.accessesCallerFrame();
+        }
 
         if (!isStatic) {
             asm.bind(unverifiedStub);
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Apr 18 23:39:07 2012 +0200
@@ -46,7 +46,9 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            tasm.frameContext.leave(tasm);
+            if (tasm.frameContext != null) {
+                tasm.frameContext.leave(tasm);
+            }
             masm.ret(0);
         }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Apr 18 23:39:07 2012 +0200
@@ -85,6 +85,12 @@
     public final RiRegisterConfig registerConfig;
 
     /**
+     * The initial frame size, not including the size of the return address.
+     * This is the constant space reserved by the runtime for all compiled methods.
+     */
+    public final int initialFrameSize;
+
+    /**
      * The final frame size, not including the size of the return address.
      * The value is only set after register allocation is complete, i.e., after all spill slots have been allocated.
      */
@@ -112,6 +118,11 @@
     private final CiStackSlot customArea;
 
     /**
+     * Records whether an offset to an incoming stack argument was ever returned by {@link #offsetForStackSlot(CiStackSlot)}.
+     */
+    private boolean accessesCallerFrame;
+
+    /**
      * Creates a new frame map for the specified method.
      */
     public FrameMap(RiRuntime runtime, CiTarget target, RiRegisterConfig registerConfig) {
@@ -123,9 +134,9 @@
         this.outgoingSize = runtime.getMinimumOutgoingSize();
         this.objectStackBlocks = new ArrayList<>();
         this.customArea = allocateStackBlock(runtime.getCustomStackAreaSize(), false);
+        this.initialFrameSize = currentFrameSize();
     }
 
-
     private int returnAddressSize() {
         return target.arch.returnAddressSize;
     }
@@ -136,6 +147,13 @@
     }
 
     /**
+     * Determines if an offset to an incoming stack argument was ever returned by {@link #offsetForStackSlot(CiStackSlot)}.
+     */
+    public boolean accessesCallerFrame() {
+        return accessesCallerFrame;
+    }
+
+    /**
      * Gets the frame size of the compiled frame, not including the size of the return address.
      * @return The size of the frame (in bytes).
      */
@@ -153,20 +171,20 @@
     }
 
     /**
-     * Sets the frame size for this frame.
-     * @param frameSize The frame size (in bytes).
+     * Gets the current size of this frame. This is the size that would be returned by
+     * {@link #frameSize()} if {@link #finish()} were called now.
      */
-    public void setFrameSize(int frameSize) {
-        assert this.frameSize == -1 : "must only be set once";
-        this.frameSize = frameSize;
+    public int currentFrameSize() {
+        return target.alignFrameSize(outgoingSize + spillSize - returnAddressSize());
     }
 
     /**
-     * Computes the frame size for this frame. After this method has been called, methods that change the
+     * Computes the final size of this frame. After this method has been called, methods that change the
      * frame size cannot be called anymore, e.g., no more spill slots or outgoing arguments can be requested.
      */
     public void finish() {
-        setFrameSize(target.alignFrameSize(outgoingSize + spillSize - returnAddressSize()));
+        assert this.frameSize == -1 : "must only be set once";
+        frameSize = currentFrameSize();
     }
 
     /**
@@ -180,6 +198,9 @@
         assert (!slot.rawAddFrameSize() && slot.rawOffset() < outgoingSize) ||
             (slot.rawAddFrameSize() && slot.rawOffset() < 0 && -slot.rawOffset() <= spillSize) ||
             (slot.rawAddFrameSize() && slot.rawOffset() >= 0);
+        if (slot.inCallerFrame()) {
+            accessesCallerFrame = true;
+        }
         return slot.offset(totalFrameSize());
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Apr 18 23:39:07 2012 +0200
@@ -54,7 +54,6 @@
      */
     private final List<Block> codeEmittingOrder;
 
-
     public final List<Code> slowPaths;
 
     public final List<Code> deoptimizationStubs;
@@ -68,6 +67,8 @@
         LIRInstruction createExchange(CiValue input1, CiValue input2);
     }
 
+    private boolean hasArgInCallerFrame;
+
     /**
      * An opaque chunk of machine code.
      */
@@ -98,15 +99,12 @@
     }
 
     /**
-     * Determines if this LIR contains any calls.
+     * Determines if any instruction in the LIR has any debug info associated with it.
      */
-    public boolean containsCalls() {
-        if (!slowPaths.isEmpty() || !deoptimizationStubs.isEmpty()) {
-            return true;
-        }
-        for (Block b : linearScanOrder) {
+    public boolean hasDebugInfo() {
+        for (Block b : linearScanOrder()) {
             for (LIRInstruction op : b.lir) {
-                if (op.hasCall()) {
+                if (op.info != null) {
                     return true;
                 }
             }
@@ -135,7 +133,9 @@
     }
 
     public void emitCode(TargetMethodAssembler tasm) {
-        tasm.frameContext.enter(tasm);
+        if (tasm.frameContext != null) {
+            tasm.frameContext.enter(tasm);
+        }
 
         for (Block b : codeEmittingOrder()) {
             emitBlock(tasm, b);
@@ -189,6 +189,18 @@
         sp.emitCode(tasm);
     }
 
+    public void setHasArgInCallerFrame() {
+        hasArgInCallerFrame = true;
+    }
+
+    /**
+     * Determines if any of the parameters to the method are passed via the stack
+     * where the parameters are located in the caller's frame.
+     */
+    public boolean hasArgInCallerFrame() {
+        return hasArgInCallerFrame;
+    }
+
 /*
     private int lastDecodeStart;
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/FrameContext.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/FrameContext.java	Wed Apr 18 23:39:07 2012 +0200
@@ -24,8 +24,7 @@
 
 
 /**
- * Emits common code for {@linkplain #enter(TargetMethodAssembler) entering} and
- * {@linkplain #leave(TargetMethodAssembler) leaving} a method.
+ * Code for managing a method's native frame.
  */
 public interface FrameContext {
     /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Apr 18 23:19:58 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Apr 18 23:39:07 2012 +0200
@@ -52,6 +52,11 @@
     public final RiRuntime runtime;
     public final FrameMap frameMap;
     public final List<Code> slowPaths;
+
+    /**
+     * The object that emits code for managing a method's frame.
+     * If null, no frame is used by the method.
+     */
     public final FrameContext frameContext;
 
     private List<ExceptionInfo> exceptionInfoList;
--- a/src/share/vm/code/nmethod.cpp	Wed Apr 18 23:19:58 2012 +0200
+++ b/src/share/vm/code/nmethod.cpp	Wed Apr 18 23:39:07 2012 +0200
@@ -833,19 +833,28 @@
     _consts_offset           = content_offset()      + code_buffer->total_offset_of(code_buffer->consts());
     _stub_offset             = content_offset()      + code_buffer->total_offset_of(code_buffer->stubs());
 
-    // Exception handler and deopt handler are in the stub section
-    assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
-    assert(offsets->value(CodeOffsets::Deopt     ) != -1, "must be set");
 #ifdef GRAAL
       // graal produces no (!) stub section
-      _exception_offset        = code_offset()          + offsets->value(CodeOffsets::Exceptions);
-      _deoptimize_offset       = code_offset()          + offsets->value(CodeOffsets::Deopt);
+      if (offsets->value(CodeOffsets::Exceptions) != -1) {
+        _exception_offset        = code_offset()          + offsets->value(CodeOffsets::Exceptions);
+      } else {
+        _exception_offset = -1;
+      }
+      if (offsets->value(CodeOffsets::Deopt) != -1) {
+        _deoptimize_offset       = code_offset()          + offsets->value(CodeOffsets::Deopt);
+      } else {
+        _deoptimize_offset = -1;
+      }
       if (offsets->value(CodeOffsets::DeoptMH) != -1) {
         _deoptimize_mh_offset  = code_offset()          + offsets->value(CodeOffsets::DeoptMH);
       } else {
         _deoptimize_mh_offset  = -1;
       }
 #else
+    // Exception handler and deopt handler are in the stub section
+    assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
+    assert(offsets->value(CodeOffsets::Deopt     ) != -1, "must be set");
+
       _exception_offset        = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
       _deoptimize_offset       = _stub_offset          + offsets->value(CodeOffsets::Deopt);
       if (offsets->value(CodeOffsets::DeoptMH) != -1) {
--- a/src/share/vm/code/nmethod.hpp	Wed Apr 18 23:19:58 2012 +0200
+++ b/src/share/vm/code/nmethod.hpp	Wed Apr 18 23:39:07 2012 +0200
@@ -340,6 +340,9 @@
   bool is_compiled_by_c2() const;
   bool is_compiled_by_shark() const;
 
+
+#define CHECK_POSITIVE(val) assert(val, "should be positive")
+
   // boundaries for different parts
   address consts_begin          () const          { return           header_begin() + _consts_offset        ; }
   address consts_end            () const          { return           header_begin() +  code_offset()        ; }
@@ -347,8 +350,8 @@
   address insts_end             () const          { return           header_begin() + _stub_offset          ; }
   address stub_begin            () const          { return           header_begin() + _stub_offset          ; }
   address stub_end              () const          { return           header_begin() + _oops_offset          ; }
-  address exception_begin       () const          { return           header_begin() + _exception_offset     ; }
-  address deopt_handler_begin   () const          { return           header_begin() + _deoptimize_offset    ; }
+  address exception_begin       () const          { assert(_exception_offset >= 0, "no exception handler"); return header_begin() + _exception_offset ; }
+  address deopt_handler_begin   () const          { assert(_deoptimize_offset >= 0, "no deopt handler"); return header_begin() + _deoptimize_offset ; }
   address deopt_mh_handler_begin() const          { return           header_begin() + _deoptimize_mh_offset ; }
   address unwind_handler_begin  () const          { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; }
   oop*    oops_begin            () const          { return (oop*)   (header_begin() + _oops_offset)         ; }
--- a/src/share/vm/graal/graalEnv.cpp	Wed Apr 18 23:19:58 2012 +0200
+++ b/src/share/vm/graal/graalEnv.cpp	Wed Apr 18 23:39:07 2012 +0200
@@ -477,9 +477,6 @@
       return NULL;
     }
 
-    assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry");
-    assert(offsets->value(CodeOffsets::Exceptions) != -1, "must have exception entry");
-
     nm =  nmethod::new_nmethod(method,
                                compile_id,
                                entry_bci,
@@ -531,13 +528,13 @@
               old->make_not_entrant();
             }
           }
-          if (TraceNMethodInstalls ) {
+          if (TraceNMethodInstalls) {
             ResourceMark rm;
             char *method_name = method->name_and_sig_as_C_string();
             ttyLocker ttyl;
-            tty->print_cr("Installing method (%d) %s ",
+            tty->print_cr("Installing method (%d) %s [entry point: %p]",
                           comp_level,
-                          method_name);
+                          method_name, nm->entry_point());
           }
           // Allow the code to be executed
           method->set_code(method, nm);