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
|