Home | History | Annotate | Download | only in lambda
      1 /*
      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 
     27 namespace art {
     28 class ArtMethod;  // forward declaration
     29 
     30 namespace mirror {
     31 class Object;  // forward declaration
     32 }  // namespace mirror
     33 
     34 namespace lambda {
     35 class 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.
     43 class ClosureBuilder {
     44  public:
     45   using ShortyTypeEnum = decltype(ShortyFieldType::kByte);
     46 
     47   // Mark this primitive value to be captured as the specified type.
     48   template <typename T, ShortyTypeEnum kShortyType = ShortyFieldTypeSelectEnum<T>::value>
     49   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 
     65   // Get the list of captured variables' shorty field types.
     66   const std::string& GetCapturedVariableShortyTypes() const;
     67 
     68   // 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_;
     98   std::string shorty_types_;
     99 };
    100 
    101 }  // namespace lambda
    102 }  // namespace art
    103 
    104 #endif  // ART_RUNTIME_LAMBDA_CLOSURE_BUILDER_H_
    105