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/interpreter/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
6 | 6 |
7 #include <fstream> | 7 #include <fstream> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
11 #include "src/builtins/builtins-arguments.h" | 11 #include "src/builtins/builtins-arguments.h" |
12 #include "src/builtins/builtins-constructor.h" | 12 #include "src/builtins/builtins-constructor.h" |
13 #include "src/code-factory.h" | 13 #include "src/code-factory.h" |
14 #include "src/compilation-info.h" | 14 #include "src/compilation-info.h" |
15 #include "src/compiler.h" | 15 #include "src/compiler.h" |
16 #include "src/factory.h" | 16 #include "src/factory.h" |
| 17 #include "src/ic/accessor-assembler.h" |
17 #include "src/interpreter/bytecode-flags.h" | 18 #include "src/interpreter/bytecode-flags.h" |
18 #include "src/interpreter/bytecode-generator.h" | 19 #include "src/interpreter/bytecode-generator.h" |
19 #include "src/interpreter/bytecodes.h" | 20 #include "src/interpreter/bytecodes.h" |
20 #include "src/interpreter/interpreter-assembler.h" | 21 #include "src/interpreter/interpreter-assembler.h" |
21 #include "src/interpreter/interpreter-intrinsics.h" | 22 #include "src/interpreter/interpreter-intrinsics.h" |
22 #include "src/log.h" | 23 #include "src/log.h" |
23 #include "src/zone/zone.h" | 24 #include "src/zone/zone.h" |
24 | 25 |
25 namespace v8 { | 26 namespace v8 { |
26 namespace internal { | 27 namespace internal { |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 // | 452 // |
452 // Stores the value of register <src> to register <dst>. | 453 // Stores the value of register <src> to register <dst>. |
453 void Interpreter::DoMov(InterpreterAssembler* assembler) { | 454 void Interpreter::DoMov(InterpreterAssembler* assembler) { |
454 Node* src_index = __ BytecodeOperandReg(0); | 455 Node* src_index = __ BytecodeOperandReg(0); |
455 Node* src_value = __ LoadRegister(src_index); | 456 Node* src_value = __ LoadRegister(src_index); |
456 Node* dst_index = __ BytecodeOperandReg(1); | 457 Node* dst_index = __ BytecodeOperandReg(1); |
457 __ StoreRegister(src_value, dst_index); | 458 __ StoreRegister(src_value, dst_index); |
458 __ Dispatch(); | 459 __ Dispatch(); |
459 } | 460 } |
460 | 461 |
461 Node* Interpreter::BuildLoadGlobal(Callable ic, Node* context, Node* name_index, | 462 void Interpreter::BuildLoadGlobal(int slot_operand_index, |
462 Node* feedback_slot, | 463 int name_operand_index, |
463 InterpreterAssembler* assembler) { | 464 TypeofMode typeof_mode, |
| 465 InterpreterAssembler* assembler) { |
464 // Load the global via the LoadGlobalIC. | 466 // Load the global via the LoadGlobalIC. |
465 Node* code_target = __ HeapConstant(ic.code()); | |
466 Node* name = __ LoadConstantPoolEntry(name_index); | |
467 Node* smi_slot = __ SmiTag(feedback_slot); | |
468 Node* feedback_vector = __ LoadFeedbackVector(); | 467 Node* feedback_vector = __ LoadFeedbackVector(); |
469 return __ CallStub(ic.descriptor(), code_target, context, name, smi_slot, | 468 Node* feedback_slot = __ BytecodeOperandIdx(slot_operand_index); |
470 feedback_vector); | 469 |
| 470 AccessorAssembler accessor_asm(assembler->state()); |
| 471 |
| 472 Label try_handler(assembler, Label::kDeferred), |
| 473 miss(assembler, Label::kDeferred); |
| 474 |
| 475 // Fast path without frame construction for the data case. |
| 476 { |
| 477 Label done(assembler); |
| 478 Variable var_result(assembler, MachineRepresentation::kTagged); |
| 479 ExitPoint exit_point(assembler, &done, &var_result); |
| 480 |
| 481 accessor_asm.LoadGlobalIC_TryPropertyCellCase( |
| 482 feedback_vector, feedback_slot, &exit_point, &try_handler, &miss, |
| 483 CodeStubAssembler::INTPTR_PARAMETERS); |
| 484 |
| 485 __ Bind(&done); |
| 486 __ SetAccumulator(var_result.value()); |
| 487 __ Dispatch(); |
| 488 } |
| 489 |
| 490 // Slow path with frame construction. |
| 491 { |
| 492 Label done(assembler); |
| 493 Variable var_result(assembler, MachineRepresentation::kTagged); |
| 494 ExitPoint exit_point(assembler, &done, &var_result); |
| 495 |
| 496 __ Bind(&try_handler); |
| 497 { |
| 498 Node* context = __ GetContext(); |
| 499 Node* smi_slot = __ SmiTag(feedback_slot); |
| 500 Node* name_index = __ BytecodeOperandIdx(name_operand_index); |
| 501 Node* name = __ LoadConstantPoolEntry(name_index); |
| 502 |
| 503 AccessorAssembler::LoadICParameters params(context, nullptr, name, |
| 504 smi_slot, feedback_vector); |
| 505 accessor_asm.LoadGlobalIC_TryHandlerCase(¶ms, typeof_mode, |
| 506 &exit_point, &miss); |
| 507 } |
| 508 |
| 509 __ Bind(&miss); |
| 510 { |
| 511 Node* context = __ GetContext(); |
| 512 Node* smi_slot = __ SmiTag(feedback_slot); |
| 513 Node* name_index = __ BytecodeOperandIdx(name_operand_index); |
| 514 Node* name = __ LoadConstantPoolEntry(name_index); |
| 515 |
| 516 AccessorAssembler::LoadICParameters params(context, nullptr, name, |
| 517 smi_slot, feedback_vector); |
| 518 accessor_asm.LoadGlobalIC_MissCase(¶ms, &exit_point); |
| 519 } |
| 520 |
| 521 __ Bind(&done); |
| 522 { |
| 523 __ SetAccumulator(var_result.value()); |
| 524 __ Dispatch(); |
| 525 } |
| 526 } |
471 } | 527 } |
472 | 528 |
473 // LdaGlobal <name_index> <slot> | 529 // LdaGlobal <name_index> <slot> |
474 // | 530 // |
475 // Load the global with name in constant pool entry <name_index> into the | 531 // Load the global with name in constant pool entry <name_index> into the |
476 // accumulator using FeedBackVector slot <slot> outside of a typeof. | 532 // accumulator using FeedBackVector slot <slot> outside of a typeof. |
477 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { | 533 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { |
478 Callable ic = | 534 static const int kNameOperandIndex = 0; |
479 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF); | 535 static const int kSlotOperandIndex = 1; |
480 | 536 |
481 Node* context = __ GetContext(); | 537 BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, NOT_INSIDE_TYPEOF, |
482 | 538 assembler); |
483 Node* name_index = __ BytecodeOperandIdx(0); | |
484 Node* raw_slot = __ BytecodeOperandIdx(1); | |
485 Node* result = BuildLoadGlobal(ic, context, name_index, raw_slot, assembler); | |
486 __ SetAccumulator(result); | |
487 __ Dispatch(); | |
488 } | 539 } |
489 | 540 |
490 // LdaGlobalInsideTypeof <name_index> <slot> | 541 // LdaGlobalInsideTypeof <name_index> <slot> |
491 // | 542 // |
492 // Load the global with name in constant pool entry <name_index> into the | 543 // Load the global with name in constant pool entry <name_index> into the |
493 // accumulator using FeedBackVector slot <slot> inside of a typeof. | 544 // accumulator using FeedBackVector slot <slot> inside of a typeof. |
494 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { | 545 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { |
495 Callable ic = | 546 static const int kNameOperandIndex = 0; |
496 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, INSIDE_TYPEOF); | 547 static const int kSlotOperandIndex = 1; |
497 | 548 |
498 Node* context = __ GetContext(); | 549 BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, INSIDE_TYPEOF, |
499 | 550 assembler); |
500 Node* name_index = __ BytecodeOperandIdx(0); | |
501 Node* raw_slot = __ BytecodeOperandIdx(1); | |
502 Node* result = BuildLoadGlobal(ic, context, name_index, raw_slot, assembler); | |
503 __ SetAccumulator(result); | |
504 __ Dispatch(); | |
505 } | 551 } |
506 | 552 |
507 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { | 553 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { |
508 // Get the global object. | 554 // Get the global object. |
509 Node* context = __ GetContext(); | 555 Node* context = __ GetContext(); |
510 Node* native_context = __ LoadNativeContext(context); | 556 Node* native_context = __ LoadNativeContext(context); |
511 Node* global = | 557 Node* global = |
512 __ LoadContextElement(native_context, Context::EXTENSION_INDEX); | 558 __ LoadContextElement(native_context, Context::EXTENSION_INDEX); |
513 | 559 |
514 // Store the global via the StoreIC. | 560 // Store the global via the StoreIC. |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 // Lookup the object with the name in constant pool entry |name_index| | 728 // Lookup the object with the name in constant pool entry |name_index| |
683 // dynamically without causing a NoReferenceError. | 729 // dynamically without causing a NoReferenceError. |
684 void Interpreter::DoLdaLookupContextSlotInsideTypeof( | 730 void Interpreter::DoLdaLookupContextSlotInsideTypeof( |
685 InterpreterAssembler* assembler) { | 731 InterpreterAssembler* assembler) { |
686 DoLdaLookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler); | 732 DoLdaLookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler); |
687 } | 733 } |
688 | 734 |
689 void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id, | 735 void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id, |
690 InterpreterAssembler* assembler) { | 736 InterpreterAssembler* assembler) { |
691 Node* context = __ GetContext(); | 737 Node* context = __ GetContext(); |
692 Node* name_index = __ BytecodeOperandIdx(0); | |
693 Node* feedback_slot = __ BytecodeOperandIdx(1); | |
694 Node* depth = __ BytecodeOperandUImm(2); | 738 Node* depth = __ BytecodeOperandUImm(2); |
695 | 739 |
696 Label slowpath(assembler, Label::kDeferred); | 740 Label slowpath(assembler, Label::kDeferred); |
697 | 741 |
698 // Check for context extensions to allow the fast path | 742 // Check for context extensions to allow the fast path |
699 __ GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath); | 743 __ GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath); |
700 | 744 |
701 // Fast path does a normal load global | 745 // Fast path does a normal load global |
702 { | 746 { |
703 Callable ic = CodeFactory::LoadGlobalICInOptimizedCode( | 747 static const int kNameOperandIndex = 0; |
704 isolate_, function_id == Runtime::kLoadLookupSlotInsideTypeof | 748 static const int kSlotOperandIndex = 1; |
705 ? INSIDE_TYPEOF | 749 |
706 : NOT_INSIDE_TYPEOF); | 750 TypeofMode typeof_mode = function_id == Runtime::kLoadLookupSlotInsideTypeof |
707 Node* result = | 751 ? INSIDE_TYPEOF |
708 BuildLoadGlobal(ic, context, name_index, feedback_slot, assembler); | 752 : NOT_INSIDE_TYPEOF; |
709 __ SetAccumulator(result); | 753 |
710 __ Dispatch(); | 754 BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, typeof_mode, |
| 755 assembler); |
711 } | 756 } |
712 | 757 |
713 // Slow path when we have to call out to the runtime | 758 // Slow path when we have to call out to the runtime |
714 __ Bind(&slowpath); | 759 __ Bind(&slowpath); |
715 { | 760 { |
| 761 Node* name_index = __ BytecodeOperandIdx(0); |
716 Node* name = __ LoadConstantPoolEntry(name_index); | 762 Node* name = __ LoadConstantPoolEntry(name_index); |
717 Node* result = __ CallRuntime(function_id, context, name); | 763 Node* result = __ CallRuntime(function_id, context, name); |
718 __ SetAccumulator(result); | 764 __ SetAccumulator(result); |
719 __ Dispatch(); | 765 __ Dispatch(); |
720 } | 766 } |
721 } | 767 } |
722 | 768 |
723 // LdaLookupGlobalSlot <name_index> <feedback_slot> <depth> | 769 // LdaLookupGlobalSlot <name_index> <feedback_slot> <depth> |
724 // | 770 // |
725 // Lookup the object with the name in constant pool entry |name_index| | 771 // Lookup the object with the name in constant pool entry |name_index| |
(...skipping 2599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3325 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 3371 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
3326 __ SmiTag(new_state)); | 3372 __ SmiTag(new_state)); |
3327 __ SetAccumulator(old_state); | 3373 __ SetAccumulator(old_state); |
3328 | 3374 |
3329 __ Dispatch(); | 3375 __ Dispatch(); |
3330 } | 3376 } |
3331 | 3377 |
3332 } // namespace interpreter | 3378 } // namespace interpreter |
3333 } // namespace internal | 3379 } // namespace internal |
3334 } // namespace v8 | 3380 } // namespace v8 |
OLD | NEW |