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/handles.h"
10 : #include "src/objects.h"
11 : #include "src/objects/slots.h"
12 : #include "src/tracing/trace-event.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // Arguments provides access to runtime call parameters.
18 : //
19 : // It uses the fact that the instance fields of Arguments
20 : // (length_, arguments_) are "overlayed" with the parameters
21 : // (no. of parameters, and the parameter pointer) passed so
22 : // that inside the C++ function, the parameters passed can
23 : // be accessed conveniently:
24 : //
25 : // Object Runtime_function(Arguments args) {
26 : // ... use args[i] here ...
27 : // }
28 : //
29 : // Note that length_ (whose value is in the integer range) is defined
30 : // as intptr_t to provide endian-neutrality on 64-bit archs.
31 :
32 : class Arguments {
33 : public:
34 : Arguments(int length, Address* arguments)
35 61814116 : : length_(length), arguments_(arguments) {
36 : DCHECK_GE(length_, 0);
37 : }
38 :
39 271083271 : Object operator[](int index) { return Object(*address_of_arg_at(index)); }
40 :
41 : template <class S = Object>
42 : inline Handle<S> at(int index);
43 :
44 : inline int smi_at(int index);
45 :
46 : inline double number_at(int index);
47 :
48 : inline void set_at(int index, Object value) {
49 644214 : *address_of_arg_at(index) = value->ptr();
50 : }
51 :
52 : inline FullObjectSlot slot_at(int index) {
53 : return FullObjectSlot(address_of_arg_at(index));
54 : }
55 :
56 : inline Address* address_of_arg_at(int index) {
57 : DCHECK_LT(static_cast<uint32_t>(index), static_cast<uint32_t>(length_));
58 455585657 : return reinterpret_cast<Address*>(reinterpret_cast<Address>(arguments_) -
59 420373669 : index * kSystemPointerSize);
60 : }
61 :
62 : // Get the total number of arguments including the receiver.
63 18696747 : int length() const { return static_cast<int>(length_); }
64 :
65 : // Arguments on the stack are in reverse order (compared to an array).
66 78 : FullObjectSlot first_slot() { return slot_at(length() - 1); }
67 : FullObjectSlot last_slot() { return slot_at(0); }
68 :
69 : private:
70 : intptr_t length_;
71 : Address* arguments_;
72 : };
73 :
74 : template <>
75 : inline Handle<Object> Arguments::at(int index) {
76 : return Handle<Object>(address_of_arg_at(index));
77 : }
78 :
79 : double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
80 :
81 : #ifdef DEBUG
82 : #define CLOBBER_DOUBLE_REGISTERS() ClobberDoubleRegisters(1, 2, 3, 4);
83 : #else
84 : #define CLOBBER_DOUBLE_REGISTERS()
85 : #endif
86 :
87 : // TODO(cbruni): add global flag to check whether any tracing events have been
88 : // enabled.
89 : #define RUNTIME_FUNCTION_RETURNS_TYPE(Type, InternalType, Convert, Name) \
90 : static V8_INLINE InternalType __RT_impl_##Name(Arguments args, \
91 : Isolate* isolate); \
92 : \
93 : V8_NOINLINE static Type Stats_##Name(int args_length, Address* args_object, \
94 : Isolate* isolate) { \
95 : RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::k##Name); \
96 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \
97 : "V8.Runtime_" #Name); \
98 : Arguments args(args_length, args_object); \
99 : return Convert(__RT_impl_##Name(args, isolate)); \
100 : } \
101 : \
102 : Type Name(int args_length, Address* args_object, Isolate* isolate) { \
103 : DCHECK(isolate->context().is_null() || isolate->context()->IsContext()); \
104 : CLOBBER_DOUBLE_REGISTERS(); \
105 : if (V8_UNLIKELY(TracingFlags::is_runtime_stats_enabled())) { \
106 : return Stats_##Name(args_length, args_object, isolate); \
107 : } \
108 : Arguments args(args_length, args_object); \
109 : return Convert(__RT_impl_##Name(args, isolate)); \
110 : } \
111 : \
112 : static InternalType __RT_impl_##Name(Arguments args, Isolate* isolate)
113 :
114 : #define CONVERT_OBJECT(x) (x)->ptr()
115 : #define CONVERT_OBJECTPAIR(x) (x)
116 :
117 : #define RUNTIME_FUNCTION(Name) \
118 : RUNTIME_FUNCTION_RETURNS_TYPE(Address, Object, CONVERT_OBJECT, Name)
119 :
120 : #define RUNTIME_FUNCTION_RETURN_PAIR(Name) \
121 : RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, ObjectPair, CONVERT_OBJECTPAIR, \
122 : Name)
123 :
124 : } // namespace internal
125 : } // namespace v8
126 :
127 : #endif // V8_ARGUMENTS_H_
|