Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_ARGUMENTS_H_
      6 #define V8_ARGUMENTS_H_
      7 
      8 #include "src/allocation.h"
      9 #include "src/objects.h"
     10 #include "src/tracing/trace-event.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 
     15 // Arguments provides access to runtime call parameters.
     16 //
     17 // It uses the fact that the instance fields of Arguments
     18 // (length_, arguments_) are "overlayed" with the parameters
     19 // (no. of parameters, and the parameter pointer) passed so
     20 // that inside the C++ function, the parameters passed can
     21 // be accessed conveniently:
     22 //
     23 //   Object* Runtime_function(Arguments args) {
     24 //     ... use args[i] here ...
     25 //   }
     26 //
     27 // Note that length_ (whose value is in the integer range) is defined
     28 // as intptr_t to provide endian-neutrality on 64-bit archs.
     29 
     30 class Arguments BASE_EMBEDDED {
     31  public:
     32   Arguments(int length, Object** arguments)
     33       : length_(length), arguments_(arguments) {
     34     DCHECK_GE(length_, 0);
     35   }
     36 
     37   Object*& operator[] (int index) {
     38     DCHECK_GE(index, 0);
     39     DCHECK_LT(static_cast<uint32_t>(index), static_cast<uint32_t>(length_));
     40     return *(reinterpret_cast<Object**>(reinterpret_cast<intptr_t>(arguments_) -
     41                                         index * kPointerSize));
     42   }
     43 
     44   template <class S = Object>
     45   inline Handle<S> at(int index);
     46 
     47   inline int smi_at(int index);
     48 
     49   inline double number_at(int index);
     50 
     51   // Get the total number of arguments including the receiver.
     52   int length() const { return static_cast<int>(length_); }
     53 
     54   Object** arguments() { return arguments_; }
     55 
     56   Object** lowest_address() { return &this->operator[](length() - 1); }
     57 
     58   Object** highest_address() { return &this->operator[](0); }
     59 
     60  private:
     61   intptr_t length_;
     62   Object** arguments_;
     63 };
     64 
     65 template <>
     66 inline Handle<Object> Arguments::at(int index) {
     67   Object** value = &((*this)[index]);
     68   return Handle<Object>(value);
     69 }
     70 
     71 double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
     72 
     73 #ifdef DEBUG
     74 #define CLOBBER_DOUBLE_REGISTERS() ClobberDoubleRegisters(1, 2, 3, 4);
     75 #else
     76 #define CLOBBER_DOUBLE_REGISTERS()
     77 #endif
     78 
     79 // TODO(cbruni): add global flag to check whether any tracing events have been
     80 // enabled.
     81 #define RUNTIME_FUNCTION_RETURNS_TYPE(Type, Name)                             \
     82   static V8_INLINE Type __RT_impl_##Name(Arguments args, Isolate* isolate);   \
     83                                                                               \
     84   V8_NOINLINE static Type Stats_##Name(int args_length, Object** args_object, \
     85                                        Isolate* isolate) {                    \
     86     RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::k##Name);      \
     87     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"),                     \
     88                  "V8.Runtime_" #Name);                                        \
     89     Arguments args(args_length, args_object);                                 \
     90     return __RT_impl_##Name(args, isolate);                                   \
     91   }                                                                           \
     92                                                                               \
     93   Type Name(int args_length, Object** args_object, Isolate* isolate) {        \
     94     DCHECK(isolate->context() == nullptr || isolate->context()->IsContext()); \
     95     CLOBBER_DOUBLE_REGISTERS();                                               \
     96     if (V8_UNLIKELY(FLAG_runtime_stats)) {                                    \
     97       return Stats_##Name(args_length, args_object, isolate);                 \
     98     }                                                                         \
     99     Arguments args(args_length, args_object);                                 \
    100     return __RT_impl_##Name(args, isolate);                                   \
    101   }                                                                           \
    102                                                                               \
    103   static Type __RT_impl_##Name(Arguments args, Isolate* isolate)
    104 
    105 #define RUNTIME_FUNCTION(Name) RUNTIME_FUNCTION_RETURNS_TYPE(Object*, Name)
    106 #define RUNTIME_FUNCTION_RETURN_PAIR(Name) \
    107     RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name)
    108 
    109 }  // namespace internal
    110 }  // namespace v8
    111 
    112 #endif  // V8_ARGUMENTS_H_
    113