diff options
author | 2015-07-30 15:11:09 -0700 | |
---|---|---|
committer | 2015-09-03 17:28:37 -0700 | |
commit | fc1ccd740b7c8e96dfac675cfc580122cd1b40a6 (patch) | |
tree | 95eb97f3cfebe13fa4c5928089ff9b7ee50c4793 /runtime/lambda/closure_builder.h | |
parent | ea33c3041e8db74d79a188703c9ec9c3879f9c1b (diff) |
lambda: Infrastructure to support capture/liberate-variable dex opcodes
* ArtLambdaMethod - wrap an ArtMethod with extra runtime lambda info
* Closure - data representation for a runtime lambda closure (read-only)
* ClosureBuilder - writer for creating a Closure at runtime
* ShortyFieldType - char/enum wrapper for shorty_field_type in dex
Tests:
* Closure, ClosureBuilder, ShortyFieldType have full unit test coverage.
* ArtLambdaMethod does not, but it is tested indirectly and is otherwise
trivial getters.
Future CLs will include interpreter integration with minimal changes to
this Closure infrastructure.
Change-Id: I38a7aea8df1da7b154fd6623258c6c228c8e51df
Diffstat (limited to 'runtime/lambda/closure_builder.h')
-rw-r--r-- | runtime/lambda/closure_builder.h | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/runtime/lambda/closure_builder.h b/runtime/lambda/closure_builder.h new file mode 100644 index 0000000000..542e12afaa --- /dev/null +++ b/runtime/lambda/closure_builder.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ART_RUNTIME_LAMBDA_CLOSURE_BUILDER_H_ +#define ART_RUNTIME_LAMBDA_CLOSURE_BUILDER_H_ + +#include "base/macros.h" +#include "base/mutex.h" // For Locks::mutator_lock_. +#include "base/value_object.h" +#include "lambda/shorty_field_type.h" + +#include <stdint.h> +#include <vector> + +namespace art { +class ArtMethod; // forward declaration + +namespace mirror { +class Object; // forward declaration +} // namespace mirror + +namespace lambda { +class ArtLambdaMethod; // forward declaration + +// Build a closure by capturing variables one at a time. +// When all variables have been marked captured, the closure can be created in-place into +// a target memory address. +// +// The mutator lock must be held for the duration of the lifetime of this object, +// since it needs to temporarily store heap references into an internal list. +class ClosureBuilder : ValueObject { + public: + using ShortyTypeEnum = decltype(ShortyFieldType::kByte); + + + // Mark this primitive value to be captured as the specified type. + template <typename T, ShortyTypeEnum kShortyType> + void CaptureVariablePrimitive(T value); + + // Mark this object reference to be captured. + void CaptureVariableObject(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); + + // Mark this lambda closure to be captured. + void CaptureVariableLambda(Closure* closure); + + // Get the size (in bytes) of the closure. + // This size is used to be able to allocate memory large enough to write the closure into. + // Call 'CreateInPlace' to actually write the closure out. + size_t GetSize() const; + + // Returns how many variables have been captured so far. + size_t GetCaptureCount() const; + + // Creates a closure in-place and writes out the data into 'memory'. + // Memory must be at least 'GetSize' bytes large. + // All previously marked data to be captured is now written out. + Closure* CreateInPlace(void* memory, ArtLambdaMethod* target_method) const + SHARED_REQUIRES(Locks::mutator_lock_); + + // Locks need to be held for entire lifetime of ClosureBuilder. + ClosureBuilder() SHARED_REQUIRES(Locks::mutator_lock_) + {} + + // Locks need to be held for entire lifetime of ClosureBuilder. + ~ClosureBuilder() SHARED_REQUIRES(Locks::mutator_lock_) + {} + + private: + // Initial size a closure starts out before any variables are written. + // Header size only. + static constexpr size_t kInitialSize = sizeof(ArtLambdaMethod*); + + // Write a Closure's variables field from the captured variables. + // variables_size specified in bytes, and only includes enough room to write variables into. + // Returns the calculated actual size of the closure. + size_t WriteValues(ArtLambdaMethod* target_method, + uint8_t variables[], + size_t header_size, + size_t variables_size) const SHARED_REQUIRES(Locks::mutator_lock_); + + size_t size_ = kInitialSize; + bool is_dynamic_size_ = false; + std::vector<ShortyFieldTypeTraits::MaxType> values_; +}; + +} // namespace lambda +} // namespace art + +#endif // ART_RUNTIME_LAMBDA_CLOSURE_BUILDER_H_ |