Line data Source code
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 1516326 : Arguments(int length, Object** arguments)
33 461188478 : : length_(length), arguments_(arguments) {
34 : DCHECK_GE(length_, 0);
35 1516326 : }
36 :
37 770717682 : Object*& operator[] (int index) {
38 : DCHECK_GE(index, 0);
39 : DCHECK_LT(static_cast<uint32_t>(index), static_cast<uint32_t>(length_));
40 3524563086 : return *(reinterpret_cast<Object**>(reinterpret_cast<intptr_t>(arguments_) -
41 3579431896 : index * kPointerSize));
42 : }
43 :
44 : template <class S = Object>
45 725751765 : 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 225 : S::cast(*value);
50 701555826 : return Handle<S>(reinterpret_cast<S**>(value));
51 : }
52 :
53 150317370 : int smi_at(int index) {
54 300634740 : return Smi::cast((*this)[index])->value();
55 : }
56 :
57 1889 : double number_at(int index) {
58 3778 : return (*this)[index]->Number();
59 : }
60 :
61 : // Get the total number of arguments including the receiver.
62 66706882 : int length() const { return static_cast<int>(length_); }
63 :
64 1516326 : Object** arguments() { return arguments_; }
65 :
66 87 : Object** lowest_address() { return &this->operator[](length() - 1); }
67 :
68 87 : 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_
|