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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 339 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
335 Node* args[] = { GetAccumulator(), | 340 Node* args[] = { GetAccumulator(), |
336 RegisterFileRawPointer(), | 341 RegisterFileRawPointer(), |
337 BytecodeOffset(), | 342 BytecodeOffset(), |
338 BytecodeArrayTaggedPointer(), | 343 BytecodeArrayTaggedPointer(), |
339 DispatchTableRawPointer(), | 344 DispatchTableRawPointer(), |
340 ContextTaggedPointer() }; | 345 ContextTaggedPointer() }; |
341 Node* tail_call = raw_assembler_->TailCallN( | 346 Node* tail_call = raw_assembler_->TailCallN( |
342 call_descriptor(), exit_trampoline_code_object, args); | 347 call_descriptor(), exit_trampoline_code_object, args); |
343 // This should always be the end node. | 348 // This should always be the end node. |
344 SetEndInput(tail_call); | 349 AddEndInput(tail_call); |
345 } | 350 } |
346 | 351 |
347 | 352 |
348 Node* InterpreterAssembler::Advance(int delta) { | 353 Node* InterpreterAssembler::Advance(int delta) { |
349 return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); | 354 return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); |
350 } | 355 } |
351 | 356 |
352 | 357 |
| 358 Node* InterpreterAssembler::Advance(Node* delta) { |
| 359 return raw_assembler_->IntPtrAdd(BytecodeOffset(), delta); |
| 360 } |
| 361 |
| 362 |
| 363 void InterpreterAssembler::Jump(Node* delta) { DispatchTo(Advance(delta)); } |
| 364 |
| 365 |
| 366 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { |
| 367 RawMachineAssembler::Label match, no_match; |
| 368 Node* condition = raw_assembler_->WordEqual(lhs, rhs); |
| 369 raw_assembler_->Branch(condition, &match, &no_match); |
| 370 raw_assembler_->Bind(&match); |
| 371 DispatchTo(Advance(delta)); |
| 372 raw_assembler_->Bind(&no_match); |
| 373 Dispatch(); |
| 374 } |
| 375 |
| 376 |
353 void InterpreterAssembler::Dispatch() { | 377 void InterpreterAssembler::Dispatch() { |
354 Node* new_bytecode_offset = Advance(interpreter::Bytecodes::Size(bytecode_)); | 378 DispatchTo(Advance(interpreter::Bytecodes::Size(bytecode_))); |
| 379 } |
| 380 |
| 381 |
| 382 void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { |
355 Node* target_bytecode = raw_assembler_->Load( | 383 Node* target_bytecode = raw_assembler_->Load( |
356 kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset); | 384 kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset); |
357 | 385 |
358 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion | 386 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion |
359 // from code object on every dispatch. | 387 // from code object on every dispatch. |
360 Node* target_code_object = raw_assembler_->Load( | 388 Node* target_code_object = raw_assembler_->Load( |
361 kMachPtr, DispatchTableRawPointer(), | 389 kMachPtr, DispatchTableRawPointer(), |
362 raw_assembler_->Word32Shl(target_bytecode, | 390 raw_assembler_->Word32Shl(target_bytecode, |
363 Int32Constant(kPointerSizeLog2))); | 391 Int32Constant(kPointerSizeLog2))); |
364 | 392 |
365 // If the order of the parameters you need to change the call signature below. | 393 // If the order of the parameters you need to change the call signature below. |
366 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 394 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); |
367 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 395 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); |
368 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 396 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); |
369 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); | 397 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); |
370 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); | 398 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); |
371 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 399 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
372 Node* args[] = { GetAccumulator(), | 400 Node* args[] = { GetAccumulator(), |
373 RegisterFileRawPointer(), | 401 RegisterFileRawPointer(), |
374 new_bytecode_offset, | 402 new_bytecode_offset, |
375 BytecodeArrayTaggedPointer(), | 403 BytecodeArrayTaggedPointer(), |
376 DispatchTableRawPointer(), | 404 DispatchTableRawPointer(), |
377 ContextTaggedPointer() }; | 405 ContextTaggedPointer() }; |
378 Node* tail_call = | 406 Node* tail_call = |
379 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); | 407 raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); |
380 // This should always be the end node. | 408 // This should always be the end node. |
381 SetEndInput(tail_call); | 409 AddEndInput(tail_call); |
382 } | 410 } |
383 | 411 |
384 | 412 |
385 void InterpreterAssembler::SetEndInput(Node* input) { | 413 void InterpreterAssembler::AddEndInput(Node* input) { |
386 DCHECK(!end_node_); | 414 DCHECK_NOT_NULL(input); |
387 end_node_ = input; | 415 end_nodes_.push_back(input); |
388 } | 416 } |
389 | 417 |
390 | 418 |
391 void InterpreterAssembler::End() { | 419 void InterpreterAssembler::End() { |
392 DCHECK(end_node_); | 420 DCHECK(!end_nodes_.empty()); |
393 // TODO(rmcilroy): Support more than 1 end input. | 421 int end_count = static_cast<int>(end_nodes_.size()); |
394 Node* end = graph()->NewNode(raw_assembler_->common()->End(1), end_node_); | 422 Node* end = graph()->NewNode(raw_assembler_->common()->End(end_count), |
| 423 end_count, &end_nodes_[0]); |
395 graph()->SetEnd(end); | 424 graph()->SetEnd(end); |
396 } | 425 } |
397 | 426 |
398 | 427 |
399 // RawMachineAssembler delegate helpers: | 428 // RawMachineAssembler delegate helpers: |
400 Isolate* InterpreterAssembler::isolate() { return raw_assembler_->isolate(); } | 429 Isolate* InterpreterAssembler::isolate() { return raw_assembler_->isolate(); } |
401 | 430 |
402 | 431 |
403 Graph* InterpreterAssembler::graph() { return raw_assembler_->graph(); } | 432 Graph* InterpreterAssembler::graph() { return raw_assembler_->graph(); } |
404 | 433 |
405 | 434 |
406 CallDescriptor* InterpreterAssembler::call_descriptor() const { | 435 CallDescriptor* InterpreterAssembler::call_descriptor() const { |
407 return raw_assembler_->call_descriptor(); | 436 return raw_assembler_->call_descriptor(); |
408 } | 437 } |
409 | 438 |
410 | 439 |
411 Schedule* InterpreterAssembler::schedule() { | 440 Schedule* InterpreterAssembler::schedule() { |
412 return raw_assembler_->schedule(); | 441 return raw_assembler_->schedule(); |
413 } | 442 } |
414 | 443 |
415 | 444 |
416 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 445 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } |
417 | 446 |
418 | 447 |
419 } // namespace interpreter | 448 } // namespace interpreter |
420 } // namespace internal | 449 } // namespace internal |
421 } // namespace v8 | 450 } // namespace v8 |
OLD | NEW |