blob: ea13eb7af698dc5cca3253ff296b214687f3ca01 [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_ART_LAMBDA_METHOD_H_
17#define ART_RUNTIME_LAMBDA_ART_LAMBDA_METHOD_H_
18
19#include "base/macros.h"
20#include "art_method.h"
21
22#include <stdint.h>
23
24namespace art {
25namespace lambda {
26
27class ArtLambdaMethod {
28 public:
29 // Construct an art lambda method.
30 // The target method is the one invoked by invoke-lambda.
31 // The type descriptor describes the types of variables captured, e.g. "ZFLObject;\FI;[Z"
32 // The shorty drops the object name and treats arrays as objects, e.g. "ZFL\L"
33 // Innate lambda means that the lambda was originally created via invoke-lambda.
34 // -- Non-innate lambdas (learned lambdas) come from a regular class that was boxed to lambda.
35 // (Ownership of strings is retained by the caller and the lifetime should exceed this class).
36 ArtLambdaMethod(ArtMethod* target_method,
37 const char* captured_variables_type_descriptor,
Igor Murashkin6918bf12015-09-27 19:19:06 -070038 const char* captured_variables_shorty,
Igor Murashkinfc1ccd72015-07-30 15:11:09 -070039 bool innate_lambda = true);
40
41 // Get the target method for this lambda that would be used by the invoke-lambda dex instruction.
42 ArtMethod* GetArtMethod() const {
43 return method_;
44 }
45
46 // Get the compile-time size of lambda closures for this method in bytes.
47 // This is circular (that is, it includes the size of the ArtLambdaMethod pointer).
48 // One should also check if the size is dynamic since nested lambdas have a runtime size.
49 size_t GetStaticClosureSize() const {
50 return closure_size_;
51 }
52
53 // Get the type descriptor for the list of captured variables.
54 // e.g. "ZFLObject;\FI;[Z" means a captured int, float, class Object, lambda FI, array of ints
55 const char* GetCapturedVariablesTypeDescriptor() const {
56 return captured_variables_type_descriptor_;
57 }
58
59 // Get the shorty 'field' type descriptor list of captured variables.
60 // This follows the same rules as a string of ShortyFieldType in the dex specification.
61 // Every captured variable is represented by exactly one character.
62 // - Objects become 'L'.
63 // - Arrays become 'L'.
64 // - Lambdas become '\'.
65 const char* GetCapturedVariablesShortyTypeDescriptor() const {
66 return captured_variables_shorty_;
67 }
68
69 // Will the size of this lambda change at runtime?
70 // Only returns true if there is a nested lambda that we can't determine statically the size of.
71 bool IsDynamicSize() const {
72 return dynamic_size_;
73 }
74
75 // Will the size of this lambda always be constant at runtime?
76 // This generally means there's no nested lambdas, or we were able to successfully determine
77 // their size statically at compile time.
78 bool IsStaticSize() const {
79 return !IsDynamicSize();
80 }
81 // Is this a lambda that was originally created via invoke-lambda?
82 // -- Non-innate lambdas (learned lambdas) come from a regular class that was boxed to lambda.
83 bool IsInnateLambda() const {
84 return innate_lambda_;
85 }
86
87 // How many variables were captured?
88 // (Each nested lambda counts as 1 captured var regardless of how many captures it itself has).
89 size_t GetNumberOfCapturedVariables() const {
90 return strlen(captured_variables_shorty_);
91 }
92
Igor Murashkinfc1ccd72015-07-30 15:11:09 -070093 private:
94 // TODO: ArtMethod, or at least the entry points should be inlined into this struct
95 // to avoid an extra indirect load when doing invokes.
96 // Target method that invoke-lambda will jump to.
97 ArtMethod* method_;
98 // How big the closure is (in bytes). Only includes the constant size.
99 size_t closure_size_;
100 // The type descriptor for the captured variables, e.g. "IS" for [int, short]
101 const char* captured_variables_type_descriptor_;
102 // The shorty type descriptor for captured vars, (e.g. using 'L' instead of 'LObject;')
103 const char* captured_variables_shorty_;
104 // Whether or not the size is dynamic. If it is, copiers need to read the Closure size at runtime.
105 bool dynamic_size_;
106 // True if this lambda was originally made with create-lambda,
107 // false if it came from a class instance (through new-instance and then unbox-lambda).
108 bool innate_lambda_;
109
110 DISALLOW_COPY_AND_ASSIGN(ArtLambdaMethod);
111};
112
113} // namespace lambda
114} // namespace art
115
116#endif // ART_RUNTIME_LAMBDA_ART_LAMBDA_METHOD_H_