• 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>
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.
length()52   int length() const { return static_cast<int>(length_); }
53 
arguments()54   Object** arguments() { return arguments_; }
55 
lowest_address()56   Object** lowest_address() { return &this->operator[](length() - 1); }
57 
highest_address()58   Object** highest_address() { return &this->operator[](0); }
59 
60  private:
61   intptr_t length_;
62   Object** arguments_;
63 };
64 
65 template <>
at(int index)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