V8 Project
linkage-impl.h
Go to the documentation of this file.
1 // Copyright 2014 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_COMPILER_LINKAGE_IMPL_H_
6 #define V8_COMPILER_LINKAGE_IMPL_H_
7 
8 namespace v8 {
9 namespace internal {
10 namespace compiler {
11 
12 // TODO(titzer): replace uses of int with size_t in LinkageHelper.
13 template <typename LinkageTraits>
15  public:
16  static const RegList kNoCalleeSaved = 0;
17 
19  DCHECK(locations->return_count_ <= 2);
20  if (locations->return_count_ > 0) {
21  locations->AddReturn(regloc(LinkageTraits::ReturnValueReg()));
22  }
23  if (locations->return_count_ > 1) {
24  locations->AddReturn(regloc(LinkageTraits::ReturnValue2Reg()));
25  }
26  }
27 
28  // TODO(turbofan): cache call descriptors for JSFunction calls.
29  static CallDescriptor* GetJSCallDescriptor(Zone* zone,
30  int js_parameter_count) {
31  const size_t return_count = 1;
32  const size_t context_count = 1;
33  const size_t parameter_count = js_parameter_count + context_count;
34 
35  LocationSignature::Builder locations(zone, return_count, parameter_count);
36  MachineSignature::Builder types(zone, return_count, parameter_count);
37 
38  // Add returns.
39  AddReturnLocations(&locations);
40  for (size_t i = 0; i < return_count; i++) {
42  }
43 
44  // All parameters to JS calls go on the stack.
45  for (int i = 0; i < js_parameter_count; i++) {
46  int spill_slot_index = i - js_parameter_count;
47  locations.AddParam(stackloc(spill_slot_index));
48  types.AddParam(kMachAnyTagged);
49  }
50  // Add context.
51  locations.AddParam(regloc(LinkageTraits::ContextReg()));
52  types.AddParam(kMachAnyTagged);
53 
54  // The target for JS function calls is the JSFunction object.
55  MachineType target_type = kMachAnyTagged;
56  LinkageLocation target_loc = regloc(LinkageTraits::JSCallFunctionReg());
57  return new (zone) CallDescriptor(CallDescriptor::kCallJSFunction, // kind
58  target_type, // target MachineType
59  target_loc, // target location
60  types.Build(), // machine_sig
61  locations.Build(), // location_sig
62  js_parameter_count, // js_parameter_count
63  Operator::kNoProperties, // properties
64  kNoCalleeSaved, // callee-saved
65  CallDescriptor::kNeedsFrameState, // flags
66  "js-call");
67  }
68 
69 
70  // TODO(turbofan): cache call descriptors for runtime calls.
71  static CallDescriptor* GetRuntimeCallDescriptor(
72  Zone* zone, Runtime::FunctionId function_id, int js_parameter_count,
73  Operator::Properties properties) {
74  const size_t function_count = 1;
75  const size_t num_args_count = 1;
76  const size_t context_count = 1;
77  const size_t parameter_count = function_count +
78  static_cast<size_t>(js_parameter_count) +
79  num_args_count + context_count;
80 
81  const Runtime::Function* function = Runtime::FunctionForId(function_id);
82  const size_t return_count = static_cast<size_t>(function->result_size);
83 
84  LocationSignature::Builder locations(zone, return_count, parameter_count);
85  MachineSignature::Builder types(zone, return_count, parameter_count);
86 
87  // Add returns.
88  AddReturnLocations(&locations);
89  for (size_t i = 0; i < return_count; i++) {
91  }
92 
93  // All parameters to the runtime call go on the stack.
94  for (int i = 0; i < js_parameter_count; i++) {
95  locations.AddParam(stackloc(i - js_parameter_count));
96  types.AddParam(kMachAnyTagged);
97  }
98  // Add runtime function itself.
99  locations.AddParam(regloc(LinkageTraits::RuntimeCallFunctionReg()));
100  types.AddParam(kMachAnyTagged);
101 
102  // Add runtime call argument count.
103  locations.AddParam(regloc(LinkageTraits::RuntimeCallArgCountReg()));
104  types.AddParam(kMachPtr);
105 
106  // Add context.
107  locations.AddParam(regloc(LinkageTraits::ContextReg()));
108  types.AddParam(kMachAnyTagged);
109 
110  CallDescriptor::Flags flags = Linkage::NeedsFrameState(function_id)
111  ? CallDescriptor::kNeedsFrameState
112  : CallDescriptor::kNoFlags;
113 
114  // The target for runtime calls is a code object.
115  MachineType target_type = kMachAnyTagged;
117  return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject, // kind
118  target_type, // target MachineType
119  target_loc, // target location
120  types.Build(), // machine_sig
121  locations.Build(), // location_sig
122  js_parameter_count, // js_parameter_count
123  properties, // properties
124  kNoCalleeSaved, // callee-saved
125  flags, // flags
126  function->name); // debug name
127  }
128 
129 
130  // TODO(turbofan): cache call descriptors for code stub calls.
131  static CallDescriptor* GetStubCallDescriptor(
132  Zone* zone, CallInterfaceDescriptor descriptor, int stack_parameter_count,
133  CallDescriptor::Flags flags) {
134  const int register_parameter_count =
135  descriptor.GetEnvironmentParameterCount();
136  const int js_parameter_count =
137  register_parameter_count + stack_parameter_count;
138  const int context_count = 1;
139  const size_t return_count = 1;
140  const size_t parameter_count =
141  static_cast<size_t>(js_parameter_count + context_count);
142 
143  LocationSignature::Builder locations(zone, return_count, parameter_count);
144  MachineSignature::Builder types(zone, return_count, parameter_count);
145 
146  // Add return location.
147  AddReturnLocations(&locations);
148  types.AddReturn(kMachAnyTagged);
149 
150  // Add parameters in registers and on the stack.
151  for (int i = 0; i < js_parameter_count; i++) {
152  if (i < register_parameter_count) {
153  // The first parameters go in registers.
154  Register reg = descriptor.GetEnvironmentParameterRegister(i);
155  locations.AddParam(regloc(reg));
156  } else {
157  // The rest of the parameters go on the stack.
158  int stack_slot = i - register_parameter_count - stack_parameter_count;
159  locations.AddParam(stackloc(stack_slot));
160  }
161  types.AddParam(kMachAnyTagged);
162  }
163  // Add context.
164  locations.AddParam(regloc(LinkageTraits::ContextReg()));
165  types.AddParam(kMachAnyTagged);
166 
167  // The target for stub calls is a code object.
168  MachineType target_type = kMachAnyTagged;
170  return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject, // kind
171  target_type, // target MachineType
172  target_loc, // target location
173  types.Build(), // machine_sig
174  locations.Build(), // location_sig
175  js_parameter_count, // js_parameter_count
176  Operator::kNoProperties, // properties
177  kNoCalleeSaved, // callee-saved registers
178  flags, // flags
179  descriptor.DebugName(zone->isolate()));
180  }
181 
182  static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone,
183  MachineSignature* msig) {
184  LocationSignature::Builder locations(zone, msig->return_count(),
185  msig->parameter_count());
186  // Add return location(s).
187  AddReturnLocations(&locations);
188 
189  // Add register and/or stack parameter(s).
190  const int parameter_count = static_cast<int>(msig->parameter_count());
191  for (int i = 0; i < parameter_count; i++) {
192  if (i < LinkageTraits::CRegisterParametersLength()) {
193  locations.AddParam(regloc(LinkageTraits::CRegisterParameter(i)));
194  } else {
195  locations.AddParam(stackloc(-1 - i));
196  }
197  }
198 
199  // The target for C calls is always an address (i.e. machine pointer).
200  MachineType target_type = kMachPtr;
202  return new (zone) CallDescriptor(CallDescriptor::kCallAddress, // kind
203  target_type, // target MachineType
204  target_loc, // target location
205  msig, // machine_sig
206  locations.Build(), // location_sig
207  0, // js_parameter_count
208  Operator::kNoProperties, // properties
209  LinkageTraits::CCalleeSaveRegisters(),
210  CallDescriptor::kNoFlags, "c-call");
211  }
212 
215  }
216 
217  static LinkageLocation stackloc(int i) {
218  DCHECK_LT(i, 0);
219  return LinkageLocation(i);
220  }
221 };
222 } // namespace compiler
223 } // namespace internal
224 } // namespace v8
225 
226 #endif // V8_COMPILER_LINKAGE_IMPL_H_
const char * DebugName(Isolate *isolate)
Register GetEnvironmentParameterRegister(int index) const
static const Function * FunctionForId(FunctionId id)
Definition: runtime.cc:9312
Isolate * isolate() const
Definition: zone.h:68
static LinkageLocation stackloc(int i)
Definition: linkage-impl.h:217
static LinkageLocation regloc(Register reg)
Definition: linkage-impl.h:213
static CallDescriptor * GetStubCallDescriptor(Zone *zone, CallInterfaceDescriptor descriptor, int stack_parameter_count, CallDescriptor::Flags flags)
Definition: linkage-impl.h:131
static CallDescriptor * GetRuntimeCallDescriptor(Zone *zone, Runtime::FunctionId function_id, int js_parameter_count, Operator::Properties properties)
Definition: linkage-impl.h:71
static CallDescriptor * GetSimplifiedCDescriptor(Zone *zone, MachineSignature *msig)
Definition: linkage-impl.h:182
static void AddReturnLocations(LocationSignature::Builder *locations)
Definition: linkage-impl.h:18
static const RegList kNoCalleeSaved
Definition: linkage-impl.h:16
static CallDescriptor * GetJSCallDescriptor(Zone *zone, int js_parameter_count)
Definition: linkage-impl.h:29
static LinkageLocation AnyRegister()
Definition: linkage.h:27
static bool NeedsFrameState(Runtime::FunctionId function)
Definition: linkage.cc:112
base::Flags< Property, uint8_t > Properties
Definition: operator.h:48
#define DCHECK(condition)
Definition: logging.h:205
#define DCHECK_LT(v1, v2)
Definition: logging.h:209
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
static int ToAllocationIndex(Register reg)