summaryrefslogtreecommitdiff
path: root/runtime/interpreter/interpreter_common.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/interpreter/interpreter_common.h')
-rw-r--r--runtime/interpreter/interpreter_common.h44
1 files changed, 23 insertions, 21 deletions
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index f57bddbb4f..5db8cf79a3 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -140,11 +140,11 @@ static inline bool IsValidLambdaTargetOrThrow(ArtMethod* called_method)
// Write out the 'Closure*' into vreg and vreg+1, as if it was a jlong.
static inline void WriteLambdaClosureIntoVRegs(ShadowFrame& shadow_frame,
- const lambda::Closure* lambda_closure,
+ const lambda::Closure& lambda_closure,
uint32_t vreg) {
// Split the method into a lo and hi 32 bits so we can encode them into 2 virtual registers.
- uint32_t closure_lo = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(lambda_closure));
- uint32_t closure_hi = static_cast<uint32_t>(reinterpret_cast<uint64_t>(lambda_closure)
+ uint32_t closure_lo = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(&lambda_closure));
+ uint32_t closure_hi = static_cast<uint32_t>(reinterpret_cast<uint64_t>(&lambda_closure)
>> BitSizeOf<uint32_t>());
// Use uint64_t instead of uintptr_t to allow shifting past the max on 32-bit.
static_assert(sizeof(uint64_t) >= sizeof(uintptr_t), "Impossible");
@@ -176,6 +176,9 @@ static inline bool DoCreateLambda(Thread* self,
DCHECK(uninitialized_closure != nullptr);
DCHECK_ALIGNED(uninitialized_closure, alignof(lambda::Closure));
+ using lambda::ArtLambdaMethod;
+ using lambda::LeakingAllocator;
+
/*
* create-lambda is opcode 0x21c
* - vA is the target register where the closure will be stored into
@@ -197,12 +200,13 @@ static inline bool DoCreateLambda(Thread* self,
return false;
}
- lambda::ArtLambdaMethod* initialized_lambda_method;
+ ArtLambdaMethod* initialized_lambda_method;
// Initialize the ArtLambdaMethod with the right data.
{
- lambda::ArtLambdaMethod* uninitialized_lambda_method =
- reinterpret_cast<lambda::ArtLambdaMethod*>(
- lambda::LeakingAllocator::AllocateMemory(self, sizeof(lambda::ArtLambdaMethod)));
+ // Allocate enough memory to store a well-aligned ArtLambdaMethod.
+ // This is not the final type yet since the data starts out uninitialized.
+ LeakingAllocator::AlignedMemoryStorage<ArtLambdaMethod>* uninitialized_lambda_method =
+ LeakingAllocator::AllocateMemory<ArtLambdaMethod>(self);
std::string captured_variables_shorty = closure_builder->GetCapturedVariableShortyTypes();
std::string captured_variables_long_type_desc;
@@ -227,30 +231,28 @@ static inline bool DoCreateLambda(Thread* self,
// Copy strings to dynamically allocated storage. This leaks, but that's ok. Fix it later.
// TODO: Strings need to come from the DexFile, so they won't need their own allocations.
- char* captured_variables_type_desc = lambda::LeakingAllocator::MakeFlexibleInstance<char>(
+ char* captured_variables_type_desc = LeakingAllocator::MakeFlexibleInstance<char>(
self,
captured_variables_long_type_desc.size() + 1);
strcpy(captured_variables_type_desc, captured_variables_long_type_desc.c_str());
- char* captured_variables_shorty_copy = lambda::LeakingAllocator::MakeFlexibleInstance<char>(
+ char* captured_variables_shorty_copy = LeakingAllocator::MakeFlexibleInstance<char>(
self,
captured_variables_shorty.size() + 1);
strcpy(captured_variables_shorty_copy, captured_variables_shorty.c_str());
- new (uninitialized_lambda_method) lambda::ArtLambdaMethod(called_method,
- captured_variables_type_desc,
- captured_variables_shorty_copy,
- true); // innate lambda
- initialized_lambda_method = uninitialized_lambda_method;
+ // After initialization, the object at the storage is well-typed. Use strong type going forward.
+ initialized_lambda_method =
+ new (uninitialized_lambda_method) ArtLambdaMethod(called_method,
+ captured_variables_type_desc,
+ captured_variables_shorty_copy,
+ true); // innate lambda
}
// Write all the closure captured variables and the closure header into the closure.
- lambda::Closure* initialized_closure;
- {
- initialized_closure =
- closure_builder->CreateInPlace(uninitialized_closure, initialized_lambda_method);
- }
+ lambda::Closure* initialized_closure =
+ closure_builder->CreateInPlace(uninitialized_closure, initialized_lambda_method);
- WriteLambdaClosureIntoVRegs(/*inout*/shadow_frame, initialized_closure, vreg_dest_closure);
+ WriteLambdaClosureIntoVRegs(/*inout*/shadow_frame, *initialized_closure, vreg_dest_closure);
return true;
}
@@ -911,7 +913,7 @@ static inline bool DoUnboxLambda(Thread* self,
}
DCHECK(unboxed_closure != nullptr);
- WriteLambdaClosureIntoVRegs(/*inout*/shadow_frame, unboxed_closure, vreg_target_closure);
+ WriteLambdaClosureIntoVRegs(/*inout*/shadow_frame, *unboxed_closure, vreg_target_closure);
return true;
}