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/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 namespace compiler { | 25 namespace compiler { |
26 | 26 |
27 | 27 |
28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, |
29 interpreter::Bytecode bytecode) | 29 interpreter::Bytecode bytecode) |
30 : bytecode_(bytecode), | 30 : bytecode_(bytecode), |
31 raw_assembler_(new RawMachineAssembler( | 31 raw_assembler_(new RawMachineAssembler( |
32 isolate, new (zone) Graph(zone), | 32 isolate, new (zone) Graph(zone), |
33 Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr, | 33 Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr, |
34 InstructionSelector::SupportedMachineOperatorFlags())), | 34 InstructionSelector::SupportedMachineOperatorFlags())), |
35 end_node_(nullptr), | 35 end_nodes_(zone), |
36 accumulator_( | 36 accumulator_( |
37 raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), | 37 raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), |
38 code_generated_(false) {} | 38 code_generated_(false) {} |
39 | 39 |
40 | 40 |
41 InterpreterAssembler::~InterpreterAssembler() {} | 41 InterpreterAssembler::~InterpreterAssembler() {} |
42 | 42 |
43 | 43 |
44 Handle<Code> InterpreterAssembler::GenerateCode() { | 44 Handle<Code> InterpreterAssembler::GenerateCode() { |
45 DCHECK(!code_generated_); | 45 DCHECK(!code_generated_); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 Node* InterpreterAssembler::NumberConstant(double value) { | 186 Node* InterpreterAssembler::NumberConstant(double value) { |
187 return raw_assembler_->NumberConstant(value); | 187 return raw_assembler_->NumberConstant(value); |
188 } | 188 } |
189 | 189 |
190 | 190 |
191 Node* InterpreterAssembler::HeapConstant(Handle<HeapObject> object) { | 191 Node* InterpreterAssembler::HeapConstant(Handle<HeapObject> object) { |
192 return raw_assembler_->HeapConstant(object); | 192 return raw_assembler_->HeapConstant(object); |
193 } | 193 } |
194 | 194 |
195 | 195 |
| 196 Node* InterpreterAssembler::BooleanConstant(bool value) { |
| 197 return raw_assembler_->BooleanConstant(value); |
| 198 } |
| 199 |
| 200 |
196 Node* InterpreterAssembler::SmiShiftBitsConstant() { | 201 Node* InterpreterAssembler::SmiShiftBitsConstant() { |
197 return Int32Constant(kSmiShiftSize + kSmiTagSize); | 202 return Int32Constant(kSmiShiftSize + kSmiTagSize); |
198 } | 203 } |
199 | 204 |
200 | 205 |
201 Node* InterpreterAssembler::SmiTag(Node* value) { | 206 Node* InterpreterAssembler::SmiTag(Node* value) { |
202 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); | 207 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); |
203 } | 208 } |
204 | 209 |
205 | 210 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 346 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
342 Node* args[] = { GetAccumulator(), | 347 Node* args[] = { GetAccumulator(), |
343 RegisterFileRawPointer(), | 348 RegisterFileRawPointer(), |
344 BytecodeOffset(), | 349 BytecodeOffset(), |
345 BytecodeArrayTaggedPointer(), | 350 BytecodeArrayTaggedPointer(), |
346 DispatchTableRawPointer(), | 351 DispatchTableRawPointer(), |
347 ContextTaggedPointer() }; | 352 ContextTaggedPointer() }; |
348 Node* tail_call = raw_assembler_->TailCallN( | 353 Node* tail_call = raw_assembler_->TailCallN( |
349 call_descriptor(), exit_trampoline_code_object, args); | 354 call_descriptor(), exit_trampoline_code_object, args); |
350 // This should always be the end node. | 355 // This should always be the end node. |
351 SetEndInput(tail_call); | 356 AddEndInput(tail_call); |
352 } | 357 } |
353 | 358 |
354 | 359 |
355 Node* InterpreterAssembler::Advance(int delta) { | 360 Node* InterpreterAssembler::Advance(int delta) { |
356 return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); | 361 return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); |
357 } | 362 } |
358 | 363 |
359 | 364 |
| 365 Node* InterpreterAssembler::Advance(Node* delta) { |
| 366 return raw_assembler_->IntPtrAdd(BytecodeOffset(), delta); |
| 367 } |
| 368 |
| 369 |
| 370 void InterpreterAssembler::Jump(Node* delta) { DispatchTo(Advance(delta)); } |
| 371 |
| 372 |
| 373 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { |
| 374 RawMachineAssembler::Label match, no_match; |
| 375 Node* condition = raw_assembler_->WordEqual(lhs, rhs); |
| 376 raw_assembler_->Branch(condition, &match, &no_match); |
| 377 raw_assembler_->Bind(&match); |
| 378 DispatchTo(Advance(delta)); |
| 379 raw_assembler_->Bind(&no_match); |
| 380 Dispatch(); |
| 381 } |
| 382 |
| 383 |
360 void InterpreterAssembler::Dispatch() { | 384 void InterpreterAssembler::Dispatch() { |
361 Node* new_bytecode_offset = Advance(interpreter::Bytecodes::Size(bytecode_)); | 385 DispatchTo(Advance(interpreter::Bytecodes::Size(bytecode_))); |
| 386 } |
| 387 |
| 388 |
| 389 void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { |
362 Node* target_bytecode = raw_assembler_->Load( | 390 Node* target_bytecode = raw_assembler_->Load( |
363 kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset); | 391 kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset); |
364 | 392 |
365 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion | 393 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion |
366 // from code object on every dispatch. | 394 // from code object on every dispatch. |
367 Node* target_code_object = raw_assembler_->Load( | 395 Node* target_code_object = raw_assembler_->Load( |
368 kMachPtr, DispatchTableRawPointer(), | 396 kMachPtr, DispatchTableRawPointer(), |
369 raw_assembler_->Word32Shl(target_bytecode, | 397 raw_assembler_->Word32Shl(target_bytecode, |
370 Int32Constant(kPointerSizeLog2))); | 398 Int32Constant(kPointerSizeLog2))); |
371 | 399 |
372 // If the order of the parameters you need to change the call signature below. | 400 // If the order of the parameters you need to change the call signature below. |
373 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 401 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); |
374 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 402 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); |
375 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 403 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); |
376 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); | 404 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); |
377 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); | 405 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); |
378 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 406 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
379 Node* args[] = { GetAccumulator(), | 407 Node* args[] = { GetAccumulator(), |
380 RegisterFileRawPointer(), | 408 RegisterFileRawPointer(), |
381 new_bytecode_offset, | 409 new_bytecode_offset, |
382 BytecodeArrayTaggedPointer(), | 410 BytecodeArrayTaggedPointer(), |
383 DispatchTableRawPointer(), | 411 DispatchTableRawPointer(), |
384 ContextTaggedPointer() }; | 412 ContextTaggedPointer() }; |
385 Node* tail_call = | 413 Node* tail_call = |
386 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); | 414 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); |
387 // This should always be the end node. | 415 // This should always be the end node. |
388 SetEndInput(tail_call); | 416 AddEndInput(tail_call); |
389 } | 417 } |
390 | 418 |
391 | 419 |
392 void InterpreterAssembler::SetEndInput(Node* input) { | 420 void InterpreterAssembler::AddEndInput(Node* input) { |
393 DCHECK(!end_node_); | 421 DCHECK_NOT_NULL(input); |
394 end_node_ = input; | 422 end_nodes_.push_back(input); |
395 } | 423 } |
396 | 424 |
397 | 425 |
398 void InterpreterAssembler::End() { | 426 void InterpreterAssembler::End() { |
399 DCHECK(end_node_); | 427 DCHECK(!end_nodes_.empty()); |
400 // TODO(rmcilroy): Support more than 1 end input. | 428 int end_count = static_cast<int>(end_nodes_.size()); |
401 Node* end = graph()->NewNode(raw_assembler_->common()->End(1), end_node_); | 429 Node* end = graph()->NewNode(raw_assembler_->common()->End(end_count), |
| 430 end_count, &end_nodes_[0]); |
402 graph()->SetEnd(end); | 431 graph()->SetEnd(end); |
403 } | 432 } |
404 | 433 |
405 | 434 |
406 // RawMachineAssembler delegate helpers: | 435 // RawMachineAssembler delegate helpers: |
407 Isolate* InterpreterAssembler::isolate() { return raw_assembler_->isolate(); } | 436 Isolate* InterpreterAssembler::isolate() { return raw_assembler_->isolate(); } |
408 | 437 |
409 | 438 |
410 Graph* InterpreterAssembler::graph() { return raw_assembler_->graph(); } | 439 Graph* InterpreterAssembler::graph() { return raw_assembler_->graph(); } |
411 | 440 |
412 | 441 |
413 CallDescriptor* InterpreterAssembler::call_descriptor() const { | 442 CallDescriptor* InterpreterAssembler::call_descriptor() const { |
414 return raw_assembler_->call_descriptor(); | 443 return raw_assembler_->call_descriptor(); |
415 } | 444 } |
416 | 445 |
417 | 446 |
418 Schedule* InterpreterAssembler::schedule() { | 447 Schedule* InterpreterAssembler::schedule() { |
419 return raw_assembler_->schedule(); | 448 return raw_assembler_->schedule(); |
420 } | 449 } |
421 | 450 |
422 | 451 |
423 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 452 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } |
424 | 453 |
425 | 454 |
426 } // namespace interpreter | 455 } // namespace interpreter |
427 } // namespace internal | 456 } // namespace internal |
428 } // namespace v8 | 457 } // namespace v8 |
OLD | NEW |