< prev index next >

src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java

Print this page
rev 47736 : 8184777: Factor out species generation logic from BoundMethodHandle
Reviewed-by: vlivanov
Contributed-by: john.r.rose@oracle.com, claes.redestad@oracle.com


 364                         m.put(k, k);
 365                     }
 366                     lambdaForm.transformCache = m;
 367                     // The second iteration will update for this query, concurrently.
 368                     continue;
 369                 }
 370                 int idx = (stale >= 0) ? stale : i;
 371                 ta[idx] = key;
 372                 return form;
 373             }
 374         }
 375     }
 376 
 377     private LambdaFormBuffer buffer() {
 378         return new LambdaFormBuffer(lambdaForm);
 379     }
 380 
 381     /// Editing methods for method handles.  These need to have fast paths.
 382 
 383     private BoundMethodHandle.SpeciesData oldSpeciesData() {
 384         return BoundMethodHandle.speciesData(lambdaForm);
 385     }

 386     private BoundMethodHandle.SpeciesData newSpeciesData(BasicType type) {
 387         return oldSpeciesData().extendWith(type);
 388     }
 389 
 390     BoundMethodHandle bindArgumentL(BoundMethodHandle mh, int pos, Object value) {
 391         assert(mh.speciesData() == oldSpeciesData());
 392         BasicType bt = L_TYPE;
 393         MethodType type2 = bindArgumentType(mh, pos, bt);
 394         LambdaForm form2 = bindArgumentForm(1+pos);
 395         return mh.copyWithExtendL(type2, form2, value);
 396     }
 397     BoundMethodHandle bindArgumentI(BoundMethodHandle mh, int pos, int value) {
 398         assert(mh.speciesData() == oldSpeciesData());
 399         BasicType bt = I_TYPE;
 400         MethodType type2 = bindArgumentType(mh, pos, bt);
 401         LambdaForm form2 = bindArgumentForm(1+pos);
 402         return mh.copyWithExtendI(type2, form2, value);
 403     }
 404 
 405     BoundMethodHandle bindArgumentJ(BoundMethodHandle mh, int pos, long value) {
 406         assert(mh.speciesData() == oldSpeciesData());
 407         BasicType bt = J_TYPE;


 444             return form;
 445         }
 446         LambdaFormBuffer buf = buffer();
 447         buf.startEdit();
 448 
 449         BoundMethodHandle.SpeciesData oldData = oldSpeciesData();
 450         BoundMethodHandle.SpeciesData newData = newSpeciesData(lambdaForm.parameterType(pos));
 451         Name oldBaseAddress = lambdaForm.parameter(0);  // BMH holding the values
 452         Name newBaseAddress;
 453         NamedFunction getter = newData.getterFunction(oldData.fieldCount());
 454 
 455         if (pos != 0) {
 456             // The newly created LF will run with a different BMH.
 457             // Switch over any pre-existing BMH field references to the new BMH class.
 458             buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress);
 459             newBaseAddress = oldBaseAddress.withConstraint(newData);
 460             buf.renameParameter(0, newBaseAddress);
 461             buf.replaceParameterByNewExpression(pos, new Name(getter, newBaseAddress));
 462         } else {
 463             // cannot bind the MH arg itself, unless oldData is empty
 464             assert(oldData == BoundMethodHandle.SpeciesData.EMPTY);
 465             newBaseAddress = new Name(L_TYPE).withConstraint(newData);
 466             buf.replaceParameterByNewExpression(0, new Name(getter, newBaseAddress));
 467             buf.insertParameter(0, newBaseAddress);
 468         }
 469 
 470         form = buf.endEdit();
 471         return putInCache(key, form);
 472     }
 473 
 474     LambdaForm addArgumentForm(int pos, BasicType type) {
 475         Transform key = Transform.of(Transform.ADD_ARG, pos, type.ordinal());
 476         LambdaForm form = getInCache(key);
 477         if (form != null) {
 478             assert(form.arity == lambdaForm.arity+1);
 479             assert(form.parameterType(pos) == type);
 480             return form;
 481         }
 482         LambdaFormBuffer buf = buffer();
 483         buf.startEdit();
 484 




 364                         m.put(k, k);
 365                     }
 366                     lambdaForm.transformCache = m;
 367                     // The second iteration will update for this query, concurrently.
 368                     continue;
 369                 }
 370                 int idx = (stale >= 0) ? stale : i;
 371                 ta[idx] = key;
 372                 return form;
 373             }
 374         }
 375     }
 376 
 377     private LambdaFormBuffer buffer() {
 378         return new LambdaFormBuffer(lambdaForm);
 379     }
 380 
 381     /// Editing methods for method handles.  These need to have fast paths.
 382 
 383     private BoundMethodHandle.SpeciesData oldSpeciesData() {
 384         return BoundMethodHandle.speciesDataFor(lambdaForm);
 385     }
 386 
 387     private BoundMethodHandle.SpeciesData newSpeciesData(BasicType type) {
 388         return oldSpeciesData().extendWith((byte) type.ordinal());
 389     }
 390 
 391     BoundMethodHandle bindArgumentL(BoundMethodHandle mh, int pos, Object value) {
 392         assert(mh.speciesData() == oldSpeciesData());
 393         BasicType bt = L_TYPE;
 394         MethodType type2 = bindArgumentType(mh, pos, bt);
 395         LambdaForm form2 = bindArgumentForm(1+pos);
 396         return mh.copyWithExtendL(type2, form2, value);
 397     }
 398     BoundMethodHandle bindArgumentI(BoundMethodHandle mh, int pos, int value) {
 399         assert(mh.speciesData() == oldSpeciesData());
 400         BasicType bt = I_TYPE;
 401         MethodType type2 = bindArgumentType(mh, pos, bt);
 402         LambdaForm form2 = bindArgumentForm(1+pos);
 403         return mh.copyWithExtendI(type2, form2, value);
 404     }
 405 
 406     BoundMethodHandle bindArgumentJ(BoundMethodHandle mh, int pos, long value) {
 407         assert(mh.speciesData() == oldSpeciesData());
 408         BasicType bt = J_TYPE;


 445             return form;
 446         }
 447         LambdaFormBuffer buf = buffer();
 448         buf.startEdit();
 449 
 450         BoundMethodHandle.SpeciesData oldData = oldSpeciesData();
 451         BoundMethodHandle.SpeciesData newData = newSpeciesData(lambdaForm.parameterType(pos));
 452         Name oldBaseAddress = lambdaForm.parameter(0);  // BMH holding the values
 453         Name newBaseAddress;
 454         NamedFunction getter = newData.getterFunction(oldData.fieldCount());
 455 
 456         if (pos != 0) {
 457             // The newly created LF will run with a different BMH.
 458             // Switch over any pre-existing BMH field references to the new BMH class.
 459             buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress);
 460             newBaseAddress = oldBaseAddress.withConstraint(newData);
 461             buf.renameParameter(0, newBaseAddress);
 462             buf.replaceParameterByNewExpression(pos, new Name(getter, newBaseAddress));
 463         } else {
 464             // cannot bind the MH arg itself, unless oldData is empty
 465             assert(oldData == BoundMethodHandle.SPECIALIZER.topSpecies());
 466             newBaseAddress = new Name(L_TYPE).withConstraint(newData);
 467             buf.replaceParameterByNewExpression(0, new Name(getter, newBaseAddress));
 468             buf.insertParameter(0, newBaseAddress);
 469         }
 470 
 471         form = buf.endEdit();
 472         return putInCache(key, form);
 473     }
 474 
 475     LambdaForm addArgumentForm(int pos, BasicType type) {
 476         Transform key = Transform.of(Transform.ADD_ARG, pos, type.ordinal());
 477         LambdaForm form = getInCache(key);
 478         if (form != null) {
 479             assert(form.arity == lambdaForm.arity+1);
 480             assert(form.parameterType(pos) == type);
 481             return form;
 482         }
 483         LambdaFormBuffer buf = buffer();
 484         buf.startEdit();
 485 


< prev index next >