< prev index next >

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

Print this page




 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;
 408         MethodType type2 = bindArgumentType(mh, pos, bt);
 409         LambdaForm form2 = bindArgumentForm(1+pos);


 430         assert(mh.form.uncustomize() == lambdaForm);
 431         assert(mh.form.names[1+pos].type == bt);
 432         assert(BasicType.basicType(mh.type().parameterType(pos)) == bt);
 433         return mh.type().dropParameterTypes(pos, pos+1);
 434     }
 435 
 436     /// Editing methods for lambda forms.
 437     // Each editing method can (potentially) cache the edited LF so that it can be reused later.
 438 
 439     LambdaForm bindArgumentForm(int pos) {
 440         Transform key = Transform.of(Transform.BIND_ARG, pos);
 441         LambdaForm form = getInCache(key);
 442         if (form != null) {
 443             assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos)));
 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         }




 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 bindArgumentQ(BoundMethodHandle mh, int pos, Object value, MethodHandle unbox) {
 391         assert(mh.speciesData() == oldSpeciesData());
 392         BasicType bt = Q_TYPE;
 393         MethodType type2 = bindArgumentType(mh, pos, bt);
 394         LambdaForm form2 = bindArgumentForm(1+pos);
 395         return mh.copyWithExtendL(type2, form2, value)
 396                  .copyWithExtendL(type2, form2, unbox);
 397     }
 398     BoundMethodHandle bindArgumentL(BoundMethodHandle mh, int pos, Object value) {
 399         assert(mh.speciesData() == oldSpeciesData());
 400         BasicType bt = L_TYPE;
 401         MethodType type2 = bindArgumentType(mh, pos, bt);
 402         LambdaForm form2 = bindArgumentForm(1+pos);
 403         return mh.copyWithExtendL(type2, form2, value);
 404     }
 405     BoundMethodHandle bindArgumentI(BoundMethodHandle mh, int pos, int value) {
 406         assert(mh.speciesData() == oldSpeciesData());
 407         BasicType bt = I_TYPE;
 408         MethodType type2 = bindArgumentType(mh, pos, bt);
 409         LambdaForm form2 = bindArgumentForm(1+pos);
 410         return mh.copyWithExtendI(type2, form2, value);
 411     }
 412 
 413     BoundMethodHandle bindArgumentJ(BoundMethodHandle mh, int pos, long value) {
 414         assert(mh.speciesData() == oldSpeciesData());
 415         BasicType bt = J_TYPE;
 416         MethodType type2 = bindArgumentType(mh, pos, bt);
 417         LambdaForm form2 = bindArgumentForm(1+pos);


 438         assert(mh.form.uncustomize() == lambdaForm);
 439         assert(mh.form.names[1+pos].type == bt);
 440         assert(BasicType.basicType(mh.type().parameterType(pos)) == bt);
 441         return mh.type().dropParameterTypes(pos, pos+1);
 442     }
 443 
 444     /// Editing methods for lambda forms.
 445     // Each editing method can (potentially) cache the edited LF so that it can be reused later.
 446 
 447     LambdaForm bindArgumentForm(int pos) {
 448         Transform key = Transform.of(Transform.BIND_ARG, pos);
 449         LambdaForm form = getInCache(key);
 450         if (form != null) {
 451             assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos)));
 452             return form;
 453         }
 454         LambdaFormBuffer buf = buffer();
 455         buf.startEdit();
 456 
 457         BoundMethodHandle.SpeciesData oldData = oldSpeciesData();
 458         BasicType ptype = lambdaForm.parameterType(pos);
 459         BoundMethodHandle.SpeciesData newData = (ptype != Q_TYPE) ? newSpeciesData(ptype)
 460                                                                   : oldData.extendWith(L_TYPE).extendWith(L_TYPE); // value + unbox MH
 461         Name oldBaseAddress = lambdaForm.parameter(0);  // BMH holding the values
 462         Name newBaseAddress;
 463         NamedFunction getter = newData.getterFunction(oldData.fieldCount());
 464 
 465         if (pos != 0) {
 466             // The newly created LF will run with a different BMH.
 467             // Switch over any pre-existing BMH field references to the new BMH class.
 468             buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress);
 469             newBaseAddress = oldBaseAddress.withConstraint(newData);
 470             buf.renameParameter(0, newBaseAddress);
 471             if (ptype == Q_TYPE) {
 472                 // Q-types are stored in boxed form. Unboxing step is required.
 473                 int exprPos = lambdaForm.arity();
 474                 int UNBOX_MH      = exprPos++;
 475                 int BOXED_VALUE   = exprPos++;
 476                 int UNBOXED_VALUE = exprPos++;
 477                 NamedFunction unboxGetter = newData.getterFunction(oldData.fieldCount()+1);
 478                 buf.insertExpression(UNBOX_MH, new Name(unboxGetter, newBaseAddress));
 479                 buf.insertExpression(BOXED_VALUE, new Name(getter, newBaseAddress));
 480                 MethodType unboxInvokerType = MethodType.methodType(Q_TYPE.basicTypeClass(), L_TYPE.basicTypeClass());
 481                 Name unbox = new Name(unboxInvokerType, buf.name(UNBOX_MH), buf.name(BOXED_VALUE));
 482                 buf.insertExpression(UNBOXED_VALUE, unbox);
 483                 buf.replaceParameterByCopy(pos, UNBOXED_VALUE);
 484             } else {
 485                 buf.replaceParameterByNewExpression(pos, new Name(getter, newBaseAddress));
 486             }
 487         } else {
 488             // cannot bind the MH arg itself, unless oldData is empty
 489             assert(oldData == BoundMethodHandle.SpeciesData.EMPTY);
 490             newBaseAddress = new Name(L_TYPE).withConstraint(newData);
 491             buf.replaceParameterByNewExpression(0, new Name(getter, newBaseAddress));
 492             buf.insertParameter(0, newBaseAddress);
 493         }
 494 
 495         form = buf.endEdit();
 496         return putInCache(key, form);
 497     }
 498 
 499     LambdaForm addArgumentForm(int pos, BasicType type) {
 500         Transform key = Transform.of(Transform.ADD_ARG, pos, type.ordinal());
 501         LambdaForm form = getInCache(key);
 502         if (form != null) {
 503             assert(form.arity == lambdaForm.arity+1);
 504             assert(form.parameterType(pos) == type);
 505             return form;
 506         }


< prev index next >