diff options
Diffstat (limited to 'runtime/interpreter/interpreter_common.h')
-rw-r--r-- | runtime/interpreter/interpreter_common.h | 44 |
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; } |