blob: 23eb484529676d1f50d3e7bd6ea4aba94d1b37ad [file] [log] [blame]
Igor Murashkinfc1ccd72015-07-30 15:11:09 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef ART_RUNTIME_LAMBDA_CLOSURE_BUILDER_H_
17#define ART_RUNTIME_LAMBDA_CLOSURE_BUILDER_H_
18
19#include "base/macros.h"
20#include "base/mutex.h" // For Locks::mutator_lock_.
21#include "base/value_object.h"
22#include "lambda/shorty_field_type.h"
23
24#include <stdint.h>
25#include <vector>
26
27namespace art {
28class ArtMethod; // forward declaration
29
30namespace mirror {
31class Object; // forward declaration
32} // namespace mirror
33
34namespace lambda {
35class ArtLambdaMethod; // forward declaration
36
37// Build a closure by capturing variables one at a time.
38// When all variables have been marked captured, the closure can be created in-place into
39// a target memory address.
40//
41// The mutator lock must be held for the duration of the lifetime of this object,
42// since it needs to temporarily store heap references into an internal list.
Igor Murashkin6918bf12015-09-27 19:19:06 -070043class ClosureBuilder {
Igor Murashkinfc1ccd72015-07-30 15:11:09 -070044 public:
45 using ShortyTypeEnum = decltype(ShortyFieldType::kByte);
46
Igor Murashkinfc1ccd72015-07-30 15:11:09 -070047 // Mark this primitive value to be captured as the specified type.
Igor Murashkin6918bf12015-09-27 19:19:06 -070048 template <typename T, ShortyTypeEnum kShortyType = ShortyFieldTypeSelectEnum<T>::value>
Igor Murashkinfc1ccd72015-07-30 15:11:09 -070049 void CaptureVariablePrimitive(T value);
50
51 // Mark this object reference to be captured.
52 void CaptureVariableObject(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_);
53
54 // Mark this lambda closure to be captured.
55 void CaptureVariableLambda(Closure* closure);
56
57 // Get the size (in bytes) of the closure.
58 // This size is used to be able to allocate memory large enough to write the closure into.
59 // Call 'CreateInPlace' to actually write the closure out.
60 size_t GetSize() const;
61
62 // Returns how many variables have been captured so far.
63 size_t GetCaptureCount() const;
64
Igor Murashkin6918bf12015-09-27 19:19:06 -070065 // Get the list of captured variables' shorty field types.
66 const std::string& GetCapturedVariableShortyTypes() const;
67
Igor Murashkinfc1ccd72015-07-30 15:11:09 -070068 // Creates a closure in-place and writes out the data into 'memory'.
69 // Memory must be at least 'GetSize' bytes large.
70 // All previously marked data to be captured is now written out.
71 Closure* CreateInPlace(void* memory, ArtLambdaMethod* target_method) const
72 SHARED_REQUIRES(Locks::mutator_lock_);
73
74 // Locks need to be held for entire lifetime of ClosureBuilder.
75 ClosureBuilder() SHARED_REQUIRES(Locks::mutator_lock_)
76 {}
77
78 // Locks need to be held for entire lifetime of ClosureBuilder.
79 ~ClosureBuilder() SHARED_REQUIRES(Locks::mutator_lock_)
80 {}
81
82 private:
83 // Initial size a closure starts out before any variables are written.
84 // Header size only.
85 static constexpr size_t kInitialSize = sizeof(ArtLambdaMethod*);
86
87 // Write a Closure's variables field from the captured variables.
88 // variables_size specified in bytes, and only includes enough room to write variables into.
89 // Returns the calculated actual size of the closure.
90 size_t WriteValues(ArtLambdaMethod* target_method,
91 uint8_t variables[],
92 size_t header_size,
93 size_t variables_size) const SHARED_REQUIRES(Locks::mutator_lock_);
94
95 size_t size_ = kInitialSize;
96 bool is_dynamic_size_ = false;
97 std::vector<ShortyFieldTypeTraits::MaxType> values_;
Igor Murashkin6918bf12015-09-27 19:19:06 -070098 std::string shorty_types_;
Igor Murashkinfc1ccd72015-07-30 15:11:09 -070099};
100
101} // namespace lambda
102} // namespace art
103
104#endif // ART_RUNTIME_LAMBDA_CLOSURE_BUILDER_H_