Re: [rvm-research] Approach for fixing the RVM-1017(Implicit unlock in synchronized method relies on local variable 0 )

Pushparaj Motamari <[email protected]>
Newsgroups gmane.comp.java.jikes.rvm.devel
Message-ID <CAKO14CXFf=9WQUvapRW4zcTRtvKr-O3JdqHwVuM2e7DZN8caKA@mail.gmail.com>
Hi,

When I build the Jikes after chanigng the GenerationContext.java as you
suggested, the precommit run successful,but when I try to run a testcase
which modifies the localvariable 0. It is failing. I am attaching the patch
and the testcase with the mail.

Thank You

Pushparaj

On Tue, Apr 30, 2013 at 3:48 AM, David P Grove <[email protected]> wrote:

> Pushparaj Motamari <[email protected]> wrote on 04/29/2013 04:32:44
> PM:
>
> >
> > I am working on the fix for RVM-1017(Implicit unlock in synchronized
> > method relies on local variable 0 ). I tried by reserving one extra
> > localword in NormalMethod.java, now it adds extra word to every
> > method, but it can be changed by putting "if(method.isSynchronized
> > ())". I am attaching the patch with the mail. When I do precommit
> > with this patch for development configuration (dacapo), some
> > testcases are failing ..like eclipse. But with prototype
> > onfiguration i.e (basic and opttests) it is successful. I would like
> > to know other approaches to fixing this.
> >
>
> Hi,
>
>  I'd think about it from the perspective of what parts of the system need
> to know how to get to the this pointer.  In addition to the obvious need of
> the compilers to generate code in the prologue/epilogue of a synchronized
> instance method to lock/unlock this, we also need to be able to unlock when
> unwinding the stack frame due to an exception being processed.  The GC will
> also need to know about it in order to make sure it is recognized as a root
> during GC and processed.
>
>  I'd also go simple first, then try to optimize it after it was working.
>
>  I think the fix to the opt compiler is actually much simpler than the
> baseline compilers.  For the opt compiler, I would just add a new temporary
> "cachedThis" in the GenerationContext and use it instead of localO in
> getLockObject.  In the prologue, add an assignment to cachedThis from
> local0.  Since the opt compiler (in GenerationContext) wraps the real body
> of the synchronized method in a generated try/catch that uses getLockObject
> to unlock this and then rethrow the exception when we need to unwind the
> method, just tweaking GenerationContext to stash away the original value of
> this should fix everything.  The fix for the opt compiler should be
> confined entirely to GenerationContext.
>
>  In the baseline compiler, things are much more annoying.  You really need
> an entry in the stackframe to hold the this pointer.  You'll need to store
> it there in the prologue, make sure the GC maps know about it, and use it
> to unlock in the method epilogue and the exception delivery code
> (unwindStackFrame in BaselineExceptionDeliverer).
>
>  You're trying to get yourself a stackslot in the baseline compiler by
> modifying NormalMethod to add an extra local word.  I think I would not
> approach it this way, because you will have to track down all the places in
> the system that do some computation based on getLocalWords() and adjust
> them.  Not pretty.  And you only need an explicit extra word in the
> stackframe for the baseline compiler.   So, I'd probably go after it by
> unconditionally making the baseline compiler's stackframe header have an
> extra word (next to the CMID), stashing the this pointer there in the
> prologue of a synchronized instance method (before the yieldpoint),
> teaching the GC mapping code to include this word for a synchronized
> instance method, and using this word to unlock in the exception handler and
> method epilogue.   After this is working robustly, then you could try to
> move it out of the fixed header and treat it as if there was an extra local
> for synchronized instance methods to avoid adding a word to the stackframe
> for all methods.  I doubt this is actually worth the complexity of doing,
> but it probably could be done.
>
> --dave
>
>
>
>
> ------------------------------------------------------------------------------
> Try New Relic Now & We'll Send You this Cool Shirt
> New Relic is the only SaaS-based application performance monitoring service
> that delivers powerful full stack analytics. Optimize and monitor your
> browser, app, & servers with just a few lines of code. Try New Relic
> and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
> _______________________________________________
> Jikesrvm-researchers mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/jikesrvm-researchers
>
>

------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr

_______________________________________________
Jikesrvm-researchers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jikesrvm-researchers
newDiff.patch (application/octet-stream, 6.5 KB)
diff -urB ./rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java ../New_UnMd/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java
--- ./rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java	2013-03-14 15:01:46.000000000 -0700
+++ ../New_UnMd/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java	2013-04-29 16:35:09.261783204 -0700
@@ -83,6 +83,7 @@
    */
   CompiledMethod original_cm;
 
+  public int numberOfArgs;
   /**
    * The method to be generated
    */
@@ -156,7 +156,7 @@
    * synchronized methods.
    */
   BasicBlock unlockAndRethrow;
-
+  public TypeReference thisTypeRef;
   /**
    * The Register to which BC2IR should assign the return value(s)
    * of the method. It will be null when the method has a void return.
@@ -192,7 +192,8 @@
    * Did BC2IR encounter a magic that requires us to allocate a stack frame?
    */
   public boolean allocFrame;
-
+  public RegisterOperand cachedThis;
+  public Register thisReg;
   /**
    * Used to communicate the meet of the return values back to the caller
    * Mainly useful when BC2IR is doing inlining....allows the caller
@@ -249,6 +250,7 @@
     int numParams = params.length;
     int argIdx = 0;
     int localNum = 0;
+    //arguments = new Operand[method.isStatic() ? numParams : numParams + 1];
     arguments = new Operand[method.isStatic() ? numParams : numParams + 1];
     // Insert IR_PROLOGUE instruction.  Loop below will fill in its operands
     Instruction prologueInstr = Prologue.create(IR_PROLOGUE, arguments.length);
@@ -257,7 +259,10 @@
     if (!method.isStatic()) {
       TypeReference thisType = meth.getDeclaringClass().getTypeRef();
       RegisterOperand thisOp = makeLocal(localNum, thisType);
-      // The this param of a virtual method is by definition non null
+     //makeLocal(method.getLocalWords()-1, thisType);
+      thisTypeRef = thisType;
+      numberOfArgs = numParams+1;
+     // The this param of a virtual method is by definition non null
       RegisterOperand guard = makeNullCheckGuard(thisOp.getRegister());
       BC2IR.setGuard(thisOp, guard);
       appendInstruction(prologue, Move.create(GUARD_MOVE, guard.copyRO(), new TrueGuardOperand()), PROLOGUE_BCI);
@@ -268,6 +273,11 @@
       }
       arguments[0] = thisOp;
       Prologue.setFormal(prologueInstr, 0, thisOp.copyU2D());
+      /* simulating aload0 , astore_method.getLocalWords-1*/
+       thisReg = temps.getReg(thisType);
+      //thisReg.setLocal();
+      cachedThis  = new RegisterOperand(thisReg,thisType);
+      appendInstruction(prologue, Move.create(IRTools.getMoveOp(thisType),cachedThis, thisOp), PROLOGUE_BCI);
       argIdx++;
       localNum++;
     }
@@ -330,11 +338,15 @@
     // Now inherit state based on callSite
     child.inlineSequence = new InlineSequence(child.method, callSite.position, callSite);
     child.enclosingHandlers = ebag;
-    child.arguments = new Operand[Call.getNumberOfParams(callSite)];
+    child.numberOfArgs = Call.getNumberOfParams(callSite);
+   // child.arguments = new Operand[Call.getNumberOfParams(callSite)];
+    child.arguments = new Operand[child.numberOfArgs];
+   // for (int i = 0; i < child.arguments.length; i++) {
     for (int i = 0; i < child.arguments.length; i++) {
       child.arguments[i] = Call.getParam(callSite, i).copy(); // copy instead
       // of clearing in case inlining aborts.
     }
+    //child.arguments[child.numberOfArgs-1]=Call.getParam(callSite, 0).copy();
     if (Call.hasResult(callSite)) {
       child.resultReg = Call.getResult(callSite).copyD2D().getRegister();
       child.resultReg.setSpansBasicBlock(); // it will...
@@ -369,9 +379,23 @@
           objPtr.setDeclaredType();
           objPtr.setType(child.method.getDeclaringClass().getTypeRef());
         }
+        RegisterOperand myOp = objPtr.copyRO();
         local = child.makeLocal(localNum, objPtr);
         localNum++;
-        child.arguments[0] = local; // Avoid confusion in BC2IR of callee
+        child.arguments[0] = local;
+        //child.makeLocal(child.method.getLocalWords()-1, myOp);
+      /*receiver = child.arguments[0];
+        objPtr = receiver.asRegister();
+        if (ClassLoaderProxy.includesType(child.method.getDeclaringClass().getTypeRef(), objPtr.getType()) != YES) {
+            // narrow type of actual to match formal static type implied by method
+            objPtr.clearPreciseType(); // Can be precise but not assignable if enough classes aren't loaded
+            objPtr.setDeclaredType();
+            objPtr.setType(child.method.getDeclaringClass().getTypeRef());
+          }
+        child.arguments[child.numberOfArgs-1]=child.makeLocal(child.method.getLocalWords(), objPtr);
+       */
+        //child.thisTypeRef =child.makeLocal(child.method.getLocalWords(), objPtr).type;
+        //child.arguments[child.numberOfArgs-1] = child.makeLocal(child.method.getLocalWords(),objPtr );// Avoid confusion in BC2IR of callee
         // when objPtr is a local in the caller.
       } else if (receiver.isConstant()) {
         local = child.makeLocal(localNum, receiver.getType());
@@ -384,11 +408,20 @@
       } else {
         OptimizingCompilerException.UNREACHABLE("Unexpected receiver operand");
       }
-      Instruction s = Move.create(REF_MOVE, local, receiver);
+
+      if(local!=null){
+child.thisReg = child.temps.getReg(local.getType());
+    //child.thisReg.setLocal();
+      child.cachedThis  = new RegisterOperand(child.thisReg,local.getType());
+  Instruction n = Move.create(IRTools.getMoveOp(local.getType()),child.cachedThis, local);
+  //s.bcIndex = PROLOGUE_BCI;
+  child.prologue.appendInstruction(n);
+ }
+    Instruction s = Move.create(REF_MOVE, local, receiver);
       s.bcIndex = PROLOGUE_BCI;
       s.position = callSite.position;
       child.prologue.appendInstruction(s);
-    }
+   }
     for (int paramIdx = 0; paramIdx < numParams; paramIdx++, argIdx++) {
       TypeReference argType = params[paramIdx];
       RegisterOperand formal;
@@ -774,8 +806,10 @@
       Offset offs = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(klass));
       return new ClassConstantOperand(klass, offs);
     } else {
-      return makeLocal(0, arguments[0].getType());
-    }
+   return new RegisterOperand(cachedThis.getRegister(), method.getDeclaringClass().getTypeRef());
+ //return new RegisterOperand(addressLocals[method.getLocalWords()],arguments[arguments.length-1].getType());
+   //new RegisterOperand(, type);
+   }
   }
 
   private void appendInstruction(BasicBlock b, Instruction s, int bcIndex) {
Only in ../New_UnMd/rvm/src/org/jikesrvm/compilers/opt/bc2ir: GenerationContext.java~
a_lk.class (application/octet-stream, 358 B) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.