OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/interpreter-assembler.h" | 5 #include "src/compiler/interpreter-assembler.h" |
6 | 6 |
7 #include <ostream> | 7 #include <ostream> |
8 | 8 |
9 #include "src/compiler/graph.h" | 9 #include "src/compiler/graph.h" |
10 #include "src/compiler/instruction-selector.h" | 10 #include "src/compiler/instruction-selector.h" |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 Node* InterpreterAssembler::SmiTag(Node* value) { | 180 Node* InterpreterAssembler::SmiTag(Node* value) { |
181 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); | 181 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); |
182 } | 182 } |
183 | 183 |
184 | 184 |
185 Node* InterpreterAssembler::SmiUntag(Node* value) { | 185 Node* InterpreterAssembler::SmiUntag(Node* value) { |
186 return raw_assembler_->WordSar(value, SmiShiftBitsConstant()); | 186 return raw_assembler_->WordSar(value, SmiShiftBitsConstant()); |
187 } | 187 } |
188 | 188 |
189 | 189 |
| 190 Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) { |
| 191 return raw_assembler_->Load(kMachAnyTagged, object, |
| 192 IntPtrConstant(offset - kHeapObjectTag)); |
| 193 } |
| 194 |
| 195 |
190 Node* InterpreterAssembler::LoadContextSlot(int slot_index) { | 196 Node* InterpreterAssembler::LoadContextSlot(int slot_index) { |
191 return raw_assembler_->Load(kMachAnyTagged, ContextTaggedPointer(), | 197 return raw_assembler_->Load(kMachAnyTagged, ContextTaggedPointer(), |
192 IntPtrConstant(Context::SlotOffset(slot_index))); | 198 IntPtrConstant(Context::SlotOffset(slot_index))); |
193 } | 199 } |
194 | 200 |
195 | 201 |
| 202 Node* InterpreterAssembler::CallJSBuiltin(Builtins::JavaScript builtin, |
| 203 Node* receiver, Node** js_args, |
| 204 int js_arg_count) { |
| 205 Node* global_object = LoadContextSlot(Context::GLOBAL_OBJECT_INDEX); |
| 206 Node* builtins_object = |
| 207 LoadObjectField(global_object, GlobalObject::kBuiltinsOffset); |
| 208 Node* function = LoadObjectField( |
| 209 builtins_object, JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); |
| 210 Node* context = LoadObjectField(function, JSFunction::kContextOffset); |
| 211 |
| 212 int index = 0; |
| 213 Node** args = zone()->NewArray<Node*>(js_arg_count + 2); |
| 214 args[index++] = receiver; |
| 215 for (int i = 0; i < js_arg_count; i++) { |
| 216 args[index++] = js_args[i]; |
| 217 } |
| 218 args[index++] = context; |
| 219 |
| 220 CallDescriptor* descriptor = Linkage::GetJSCallDescriptor( |
| 221 zone(), false, js_arg_count + 1, CallDescriptor::kNoFlags); |
| 222 return raw_assembler_->CallN(descriptor, function, args); |
| 223 } |
| 224 |
| 225 |
| 226 Node* InterpreterAssembler::CallJSBuiltin(Builtins::JavaScript builtin, |
| 227 Node* receiver) { |
| 228 return CallJSBuiltin(builtin, receiver, nullptr, 0); |
| 229 } |
| 230 |
| 231 |
| 232 Node* InterpreterAssembler::CallJSBuiltin(Builtins::JavaScript builtin, |
| 233 Node* receiver, Node* arg1) { |
| 234 return CallJSBuiltin(builtin, receiver, &arg1, 1); |
| 235 } |
| 236 |
| 237 |
196 void InterpreterAssembler::Return() { | 238 void InterpreterAssembler::Return() { |
197 Node* exit_trampoline_code_object = | 239 Node* exit_trampoline_code_object = |
198 HeapConstant(Unique<HeapObject>::CreateImmovable( | 240 HeapConstant(Unique<HeapObject>::CreateImmovable( |
199 isolate()->builtins()->InterpreterExitTrampoline())); | 241 isolate()->builtins()->InterpreterExitTrampoline())); |
200 // If the order of the parameters you need to change the call signature below. | 242 // If the order of the parameters you need to change the call signature below. |
201 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 243 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); |
202 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 244 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); |
203 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 245 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); |
204 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); | 246 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); |
205 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); | 247 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); |
206 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 248 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
207 Node* tail_call = raw_assembler_->TailCallInterpreterDispatch( | 249 Node* args[] = { GetAccumulator(), |
208 call_descriptor(), exit_trampoline_code_object, GetAccumulator(), | 250 RegisterFileRawPointer(), |
209 RegisterFileRawPointer(), BytecodeOffset(), BytecodeArrayTaggedPointer(), | 251 BytecodeOffset(), |
210 DispatchTableRawPointer(), ContextTaggedPointer()); | 252 BytecodeArrayTaggedPointer(), |
| 253 DispatchTableRawPointer(), |
| 254 ContextTaggedPointer() }; |
| 255 Node* tail_call = raw_assembler_->TailCallN( |
| 256 call_descriptor(), exit_trampoline_code_object, args); |
211 // This should always be the end node. | 257 // This should always be the end node. |
212 SetEndInput(tail_call); | 258 SetEndInput(tail_call); |
213 } | 259 } |
214 | 260 |
215 | 261 |
216 Node* InterpreterAssembler::Advance(int delta) { | 262 Node* InterpreterAssembler::Advance(int delta) { |
217 return raw_assembler_->IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); | 263 return raw_assembler_->IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); |
218 } | 264 } |
219 | 265 |
220 | 266 |
221 void InterpreterAssembler::Dispatch() { | 267 void InterpreterAssembler::Dispatch() { |
222 Node* new_bytecode_offset = Advance(interpreter::Bytecodes::Size(bytecode_)); | 268 Node* new_bytecode_offset = Advance(interpreter::Bytecodes::Size(bytecode_)); |
223 Node* target_bytecode = raw_assembler_->Load( | 269 Node* target_bytecode = raw_assembler_->Load( |
224 kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset); | 270 kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset); |
225 | 271 |
226 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion | 272 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion |
227 // from code object on every dispatch. | 273 // from code object on every dispatch. |
228 Node* target_code_object = raw_assembler_->Load( | 274 Node* target_code_object = raw_assembler_->Load( |
229 kMachPtr, DispatchTableRawPointer(), | 275 kMachPtr, DispatchTableRawPointer(), |
230 raw_assembler_->Word32Shl(target_bytecode, | 276 raw_assembler_->Word32Shl(target_bytecode, |
231 Int32Constant(kPointerSizeLog2))); | 277 Int32Constant(kPointerSizeLog2))); |
232 | 278 |
233 // If the order of the parameters you need to change the call signature below. | 279 // If the order of the parameters you need to change the call signature below. |
234 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 280 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); |
235 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 281 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); |
236 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 282 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); |
237 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); | 283 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); |
238 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); | 284 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); |
239 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 285 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
240 Node* tail_call = raw_assembler_->TailCallInterpreterDispatch( | 286 Node* args[] = { GetAccumulator(), |
241 call_descriptor(), target_code_object, GetAccumulator(), | 287 RegisterFileRawPointer(), |
242 RegisterFileRawPointer(), new_bytecode_offset, | 288 new_bytecode_offset, |
243 BytecodeArrayTaggedPointer(), DispatchTableRawPointer(), | 289 BytecodeArrayTaggedPointer(), |
244 ContextTaggedPointer()); | 290 DispatchTableRawPointer(), |
| 291 ContextTaggedPointer() }; |
| 292 Node* tail_call = |
| 293 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); |
245 // This should always be the end node. | 294 // This should always be the end node. |
246 SetEndInput(tail_call); | 295 SetEndInput(tail_call); |
247 } | 296 } |
248 | 297 |
249 | 298 |
250 void InterpreterAssembler::SetEndInput(Node* input) { | 299 void InterpreterAssembler::SetEndInput(Node* input) { |
251 DCHECK(!end_node_); | 300 DCHECK(!end_node_); |
252 end_node_ = input; | 301 end_node_ = input; |
253 } | 302 } |
254 | 303 |
(...skipping 16 matching lines...) Expand all Loading... |
271 CallDescriptor* InterpreterAssembler::call_descriptor() const { | 320 CallDescriptor* InterpreterAssembler::call_descriptor() const { |
272 return raw_assembler_->call_descriptor(); | 321 return raw_assembler_->call_descriptor(); |
273 } | 322 } |
274 | 323 |
275 | 324 |
276 Schedule* InterpreterAssembler::schedule() { | 325 Schedule* InterpreterAssembler::schedule() { |
277 return raw_assembler_->schedule(); | 326 return raw_assembler_->schedule(); |
278 } | 327 } |
279 | 328 |
280 | 329 |
| 330 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } |
| 331 |
281 | 332 |
282 } // namespace interpreter | 333 } // namespace interpreter |
283 } // namespace internal | 334 } // namespace internal |
284 } // namespace v8 | 335 } // namespace v8 |
OLD | NEW |