From 457e874459ae638145cab6d572e34d48480e39d2 Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Thu, 22 Oct 2015 17:37:50 -0700 Subject: lambda: Add support for invoke-interface for boxed innate lambdas Lambda closures created with the 'create-lambda' instruction (termed "innate lambdas") can be turned into an object with 'box-lambda'. This CL enables support for those kinds of lambdas to work with 'invoke-interface' by generating a proxy class for the lambda. Note: MIPS32/64 support not included. Bug: 24618608 Bug: 25107649 Change-Id: Ic8f1bb66ebeaed4097e758a50becf1cff6ccaefb --- runtime/lambda/closure_builder.cc | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'runtime/lambda/closure_builder.cc') diff --git a/runtime/lambda/closure_builder.cc b/runtime/lambda/closure_builder.cc index 739e965238..7b36042921 100644 --- a/runtime/lambda/closure_builder.cc +++ b/runtime/lambda/closure_builder.cc @@ -75,7 +75,7 @@ void ClosureBuilder::CaptureVariableLambda(Closure* closure) { if (LIKELY(is_dynamic_size_ == false)) { // Write in the extra bytes to store the dynamic size the first time. is_dynamic_size_ = true; - size_ += sizeof(Closure::captured_[0].dynamic_.size_); + size_ += sizeof(ClosureStorage::captured_[0].dynamic_.size_); } // A closure may be sized dynamically, so always query it for the true size. @@ -107,38 +107,40 @@ Closure* ClosureBuilder::CreateInPlace(void* memory, ArtLambdaMethod* target_met << "number of variables captured at runtime does not match " << "number of variables captured at compile time"; - Closure* closure = new (memory) Closure; - closure->lambda_info_ = target_method; + ClosureStorage* closure_storage = new (memory) ClosureStorage; + closure_storage->lambda_info_ = target_method; - static_assert(offsetof(Closure, captured_) == kInitialSize, "wrong initial size"); + static_assert(offsetof(ClosureStorage, captured_) == kInitialSize, "wrong initial size"); size_t written_size; if (UNLIKELY(is_dynamic_size_)) { // The closure size must be set dynamically (i.e. nested lambdas). - closure->captured_[0].dynamic_.size_ = GetSize(); - size_t header_size = offsetof(Closure, captured_[0].dynamic_.variables_); + closure_storage->captured_[0].dynamic_.size_ = GetSize(); + size_t header_size = offsetof(ClosureStorage, captured_[0].dynamic_.variables_); DCHECK_LE(header_size, GetSize()); size_t variables_size = GetSize() - header_size; written_size = WriteValues(target_method, - closure->captured_[0].dynamic_.variables_, + closure_storage->captured_[0].dynamic_.variables_, header_size, variables_size); } else { // The closure size is known statically (i.e. no nested lambdas). DCHECK(GetSize() == target_method->GetStaticClosureSize()); - size_t header_size = offsetof(Closure, captured_[0].static_variables_); + size_t header_size = offsetof(ClosureStorage, captured_[0].static_variables_); DCHECK_LE(header_size, GetSize()); size_t variables_size = GetSize() - header_size; written_size = WriteValues(target_method, - closure->captured_[0].static_variables_, + closure_storage->captured_[0].static_variables_, header_size, variables_size); } - DCHECK_EQ(written_size, closure->GetSize()); + // OK: The closure storage is guaranteed to be the same as a closure. + Closure* closure = reinterpret_cast(closure_storage); + DCHECK_EQ(written_size, closure->GetSize()); return closure; } -- cgit v1.2.3-59-g8ed1b