• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-inl.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:
Arguments(int length,Object ** arguments)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 
at(int index)44   template <class S> Handle<S> at(int index) {
45     Object** value = &((*this)[index]);
46     // This cast checks that the object we're accessing does indeed have the
47     // expected type.
48     S::cast(*value);
49     return Handle<S>(reinterpret_cast<S**>(value));
50   }
51 
smi_at(int index)52   int smi_at(int index) {
53     return Smi::cast((*this)[index])->value();
54   }
55 
number_at(int index)56   double number_at(int index) {
57     return (*this)[index]->Number();
58   }
59 
60   // Get the total number of arguments including the receiver.
length()61   int length() const { return static_cast<int>(length_); }
62 
arguments()63   Object** arguments() { return arguments_; }
64 
lowest_address()65   Object** lowest_address() { return &this->operator[](length() - 1); }
66 
highest_address()67   Object** highest_address() { return &this->operator[](0); }
68 
69  private:
70   intptr_t length_;
71   Object** arguments_;
72 };
73 
74 double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
75 
76 #ifdef DEBUG
77 #define CLOBBER_DOUBLE_REGISTERS() ClobberDoubleRegisters(1, 2, 3, 4);
78 #else
79 #define CLOBBER_DOUBLE_REGISTERS()
80 #endif
81 
82 // TODO(cbruni): add global flag to check whether any tracing events have been
83 // enabled.
84 #define RUNTIME_FUNCTION_RETURNS_TYPE(Type, Name)                             \
85   static INLINE(Type __RT_impl_##Name(Arguments args, Isolate* isolate));     \
86                                                                               \
87   V8_NOINLINE static Type Stats_##Name(int args_length, Object** args_object, \
88                                        Isolate* isolate) {                    \
89     RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::Name);            \
90     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"),                     \
91                  "V8.Runtime_" #Name);                                        \
92     Arguments args(args_length, args_object);                                 \
93     return __RT_impl_##Name(args, isolate);                                   \
94   }                                                                           \
95                                                                               \
96   Type Name(int args_length, Object** args_object, Isolate* isolate) {        \
97     CLOBBER_DOUBLE_REGISTERS();                                               \
98     if (FLAG_runtime_call_stats) {                                            \
99       return Stats_##Name(args_length, args_object, isolate);                 \
100     }                                                                         \
101     Arguments args(args_length, args_object);                                 \
102     return __RT_impl_##Name(args, isolate);                                   \
103   }                                                                           \
104                                                                               \
105   static Type __RT_impl_##Name(Arguments args, Isolate* isolate)
106 
107 #define RUNTIME_FUNCTION(Name) RUNTIME_FUNCTION_RETURNS_TYPE(Object*, Name)
108 #define RUNTIME_FUNCTION_RETURN_PAIR(Name) \
109     RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name)
110 #define RUNTIME_FUNCTION_RETURN_TRIPLE(Name) \
111     RUNTIME_FUNCTION_RETURNS_TYPE(ObjectTriple, Name)
112 
113 }  // namespace internal
114 }  // namespace v8
115 
116 #endif  // V8_ARGUMENTS_H_
117