summaryrefslogtreecommitdiff
path: root/runtime/interpreter/interpreter_common.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/interpreter/interpreter_common.cc')
-rw-r--r--runtime/interpreter/interpreter_common.cc57
1 files changed, 3 insertions, 54 deletions
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 1fcace6d3b..c5e54436e1 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -439,7 +439,7 @@ static bool DoVarHandleInvokeCommon(Thread* self,
bool is_var_args = inst->HasVarArgs();
const uint32_t vRegC = is_var_args ? inst->VRegC_45cc() : inst->VRegC_4rcc();
const uint16_t vRegH = is_var_args ? inst->VRegH_45cc() : inst->VRegH_4rcc();
- StackHandleScope<4> hs(self);
+ StackHandleScope<3> hs(self);
Handle<mirror::VarHandle> var_handle = hs.NewHandle(
ObjPtr<mirror::VarHandle>::DownCast(shadow_frame.GetVRegReference(vRegC)));
ArtMethod* method = shadow_frame.GetMethod();
@@ -458,63 +458,12 @@ static bool DoVarHandleInvokeCommon(Thread* self,
all_operands = &range_operands.value();
}
NoReceiverInstructionOperands operands(all_operands);
- ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
- // If the `ThreadLocalRandom` class is not yet initialized, do the `VarHandle` operation
- // without creating a managed `MethodType` object. This avoids a circular initialization
- // issue when `ThreadLocalRandom.<clinit>` indirectly calls `AtomicLong.compareAndSet()`
- // (implemented with a `VarHandle`) and the `MethodType` caching circles back to the
- // `ThreadLocalRandom` with uninitialized `seeder` and throws NPE.
- //
- // Do a quick test for "visibly initialized" without a read barrier and, if that fails,
- // do a thorough test for "initialized" (including load acquire) with the read barrier.
- ArtField* field = WellKnownClasses::java_util_concurrent_ThreadLocalRandom_seeder;
- if (LIKELY(field->GetDeclaringClass<kWithoutReadBarrier>()->IsVisiblyInitialized()) ||
- field->GetDeclaringClass()->IsInitialized()) {
- Handle<mirror::MethodType> callsite_type(hs.NewHandle(
- class_linker->ResolveMethodType(self, dex::ProtoIndex(vRegH), dex_cache, class_loader)));
- if (LIKELY(callsite_type != nullptr)) {
- return VarHandleInvokeAccessor(self,
- shadow_frame,
- var_handle,
- callsite_type,
- access_mode,
- &operands,
- result);
- }
- // This implies we couldn't resolve one or more types in this VarHandle,
- // or we could not allocate the `MethodType` object.
- CHECK(self->IsExceptionPending());
- if (self->GetException()->GetClass() != WellKnownClasses::java_lang_OutOfMemoryError.Get()) {
- return false;
- }
- // Clear the OOME and retry without creating an actual `MethodType` object.
- // This prevents unexpected OOME for trivial `VarHandle` operations.
- // It also prevents odd situations where a `VarHandle` operation succeeds but the same
- // operation fails later because the `MethodType` object was evicted from the `DexCache`
- // and we suddenly run out of memory to allocate a new one.
- //
- // We have previously seen OOMEs in the run-test `183-rmw-stress-test` with
- // `--optimizng --no-image` (boot class path methods run in interpreter without JIT)
- // but it probably happened on the first execution of a trivial `VarHandle` operation
- // and not due to the `DexCache` eviction mentioned above.
- self->ClearException();
- }
-
- VariableSizedHandleScope callsite_type_hs(self);
- mirror::RawMethodType callsite_type(&callsite_type_hs);
- if (!class_linker->ResolveMethodType(self,
- dex::ProtoIndex(vRegH),
- dex_cache,
- class_loader,
- callsite_type)) {
- CHECK(self->IsExceptionPending());
- return false;
- }
return VarHandleInvokeAccessor(self,
shadow_frame,
+ method,
var_handle,
- callsite_type,
+ dex::ProtoIndex(vRegH),
access_mode,
&operands,
result);