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