diff options
Diffstat (limited to 'runtime/lambda/art_lambda_method.h')
-rw-r--r-- | runtime/lambda/art_lambda_method.h | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/runtime/lambda/art_lambda_method.h b/runtime/lambda/art_lambda_method.h new file mode 100644 index 0000000000..892d8c6f6b --- /dev/null +++ b/runtime/lambda/art_lambda_method.h @@ -0,0 +1,116 @@ +/* + * 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_ART_LAMBDA_METHOD_H_ +#define ART_RUNTIME_LAMBDA_ART_LAMBDA_METHOD_H_ + +#include "base/macros.h" +#include "art_method.h" + +#include <stdint.h> + +namespace art { +namespace lambda { + +class ArtLambdaMethod { + public: + // Construct an art lambda method. + // The target method is the one invoked by invoke-lambda. + // The type descriptor describes the types of variables captured, e.g. "ZFLObject;\FI;[Z" + // The shorty drops the object name and treats arrays as objects, e.g. "ZFL\L" + // Innate lambda means that the lambda was originally created via invoke-lambda. + // -- Non-innate lambdas (learned lambdas) come from a regular class that was boxed to lambda. + // (Ownership of strings is retained by the caller and the lifetime should exceed this class). + ArtLambdaMethod(ArtMethod* target_method, + const char* captured_variables_type_descriptor, + const char* captured_variables_shorty_, + bool innate_lambda = true); + + // Get the target method for this lambda that would be used by the invoke-lambda dex instruction. + ArtMethod* GetArtMethod() const { + return method_; + } + + // Get the compile-time size of lambda closures for this method in bytes. + // This is circular (that is, it includes the size of the ArtLambdaMethod pointer). + // One should also check if the size is dynamic since nested lambdas have a runtime size. + size_t GetStaticClosureSize() const { + return closure_size_; + } + + // Get the type descriptor for the list of captured variables. + // e.g. "ZFLObject;\FI;[Z" means a captured int, float, class Object, lambda FI, array of ints + const char* GetCapturedVariablesTypeDescriptor() const { + return captured_variables_type_descriptor_; + } + + // Get the shorty 'field' type descriptor list of captured variables. + // This follows the same rules as a string of ShortyFieldType in the dex specification. + // Every captured variable is represented by exactly one character. + // - Objects become 'L'. + // - Arrays become 'L'. + // - Lambdas become '\'. + const char* GetCapturedVariablesShortyTypeDescriptor() const { + return captured_variables_shorty_; + } + + // Will the size of this lambda change at runtime? + // Only returns true if there is a nested lambda that we can't determine statically the size of. + bool IsDynamicSize() const { + return dynamic_size_; + } + + // Will the size of this lambda always be constant at runtime? + // This generally means there's no nested lambdas, or we were able to successfully determine + // their size statically at compile time. + bool IsStaticSize() const { + return !IsDynamicSize(); + } + // Is this a lambda that was originally created via invoke-lambda? + // -- Non-innate lambdas (learned lambdas) come from a regular class that was boxed to lambda. + bool IsInnateLambda() const { + return innate_lambda_; + } + + // How many variables were captured? + // (Each nested lambda counts as 1 captured var regardless of how many captures it itself has). + size_t GetNumberOfCapturedVariables() const { + return strlen(captured_variables_shorty_); + } + + private: + // TODO: ArtMethod, or at least the entry points should be inlined into this struct + // to avoid an extra indirect load when doing invokes. + // Target method that invoke-lambda will jump to. + ArtMethod* method_; + // How big the closure is (in bytes). Only includes the constant size. + size_t closure_size_; + // The type descriptor for the captured variables, e.g. "IS" for [int, short] + const char* captured_variables_type_descriptor_; + // The shorty type descriptor for captured vars, (e.g. using 'L' instead of 'LObject;') + const char* captured_variables_shorty_; + // Whether or not the size is dynamic. If it is, copiers need to read the Closure size at runtime. + bool dynamic_size_; + // True if this lambda was originally made with create-lambda, + // false if it came from a class instance (through new-instance and then unbox-lambda). + bool innate_lambda_; + + DISALLOW_COPY_AND_ASSIGN(ArtLambdaMethod); +}; + +} // namespace lambda +} // namespace art + +#endif // ART_RUNTIME_LAMBDA_ART_LAMBDA_METHOD_H_ |