Chromium Code Reviews| 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( |
| 462 Node* feedback_slot, | 463 const std::function<compiler::Node*()>& gen_name_index, Node* feedback_slot, |
|
Igor Sheludko
2017/02/08 15:42:20
Given that you already sawed LoadGlobalIC into bui
rmcilroy
2017/02/08 17:39:14
+1 I think you should be able to just pass the nam
Igor Sheludko
2017/02/08 17:44:40
The idea is to remove everything related to name f
Igor Sheludko
2017/02/08 17:46:25
And in my comment above I meant to pass indices as
rmcilroy
2017/02/08 18:38:21
I see. I could live with the bytecode operand inde
jgruber
2017/02/09 09:32:51
This is what I went with, BuildLoadGlobal now take
| |
| 463 InterpreterAssembler* assembler) { | 464 TypeofMode typeof_mode, InterpreterAssembler* assembler) { |
| 464 // Load the global via the LoadGlobalIC. | 465 // 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); | 466 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 |
| 470 feedback_vector); | 469 AccessorAssembler accessor_asm(assembler->state()); |
| 470 | |
| 471 Label try_handler(assembler, Label::kDeferred), | |
| 472 miss(assembler, Label::kDeferred); | |
| 473 | |
| 474 // Fast path without frame construction for the data case. | |
| 475 { | |
| 476 Label out(assembler); | |
|
rmcilroy
2017/02/08 18:38:21
nit - "done" is used more commonly.
jgruber
2017/02/09 09:32:51
Done.
| |
| 477 Variable var_result(assembler, MachineRepresentation::kTagged); | |
| 478 ExitPoint exit_point(assembler, &out, &var_result); | |
| 479 | |
| 480 AccessorAssembler::LoadICParameters p(nullptr, nullptr, nullptr, smi_slot, | |
|
rmcilroy
2017/02/08 18:38:21
nit - params
jgruber
2017/02/09 09:32:51
These have been removed.
| |
| 481 feedback_vector); | |
| 482 accessor_asm.LoadGlobalICData(&p, &exit_point, &try_handler, &miss); | |
|
Igor Sheludko
2017/02/08 15:42:20
s/&p/feedback_vector, smi_slot/
jgruber
2017/02/09 09:32:51
Done. Also removed smi tagging for the fast path.
| |
| 483 | |
| 484 __ Bind(&out); | |
| 485 __ SetAccumulator(var_result.value()); | |
| 486 __ Dispatch(); | |
| 487 } | |
| 488 | |
| 489 // Slow path with frame construction. | |
| 490 { | |
| 491 Label out(assembler); | |
|
rmcilroy
2017/02/08 18:38:21
ditto.
jgruber
2017/02/09 09:32:51
Done.
| |
| 492 Variable var_result(assembler, MachineRepresentation::kTagged); | |
| 493 ExitPoint exit_point(assembler, &out, &var_result); | |
| 494 | |
| 495 __ Bind(&try_handler); | |
| 496 { | |
| 497 Node* context = __ GetContext(); | |
| 498 Node* name = __ LoadConstantPoolEntry(gen_name_index()); | |
| 499 | |
| 500 AccessorAssembler::LoadICParameters p(context, nullptr, name, smi_slot, | |
|
rmcilroy
2017/02/08 18:38:21
ditto
jgruber
2017/02/09 09:32:51
Done.
| |
| 501 feedback_vector); | |
| 502 accessor_asm.LoadGlobalICHandler(&p, typeof_mode, &exit_point, &miss); | |
| 503 } | |
| 504 | |
| 505 __ Bind(&miss); | |
| 506 { | |
| 507 Node* context = __ GetContext(); | |
| 508 Node* name = __ LoadConstantPoolEntry(gen_name_index()); | |
| 509 | |
| 510 AccessorAssembler::LoadICParameters p(context, nullptr, name, smi_slot, | |
| 511 feedback_vector); | |
| 512 accessor_asm.LoadGlobalICMiss(&p, &exit_point); | |
| 513 } | |
| 514 | |
| 515 __ Bind(&out); | |
| 516 { | |
| 517 __ SetAccumulator(var_result.value()); | |
| 518 __ Dispatch(); | |
| 519 } | |
| 520 } | |
| 471 } | 521 } |
| 472 | 522 |
| 473 // LdaGlobal <name_index> <slot> | 523 // LdaGlobal <name_index> <slot> |
| 474 // | 524 // |
| 475 // Load the global with name in constant pool entry <name_index> into the | 525 // Load the global with name in constant pool entry <name_index> into the |
| 476 // accumulator using FeedBackVector slot <slot> outside of a typeof. | 526 // accumulator using FeedBackVector slot <slot> outside of a typeof. |
| 477 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { | 527 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { |
| 478 Callable ic = | 528 Node* raw_slot = __ BytecodeOperandIdx(1); |
| 479 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF); | |
| 480 | 529 |
| 481 Node* context = __ GetContext(); | 530 auto gen_name_index = [=]() { return __ BytecodeOperandIdx(0); }; |
| 482 | 531 |
| 483 Node* name_index = __ BytecodeOperandIdx(0); | 532 BuildLoadGlobal(gen_name_index, raw_slot, NOT_INSIDE_TYPEOF, assembler); |
| 484 Node* raw_slot = __ BytecodeOperandIdx(1); | |
| 485 Node* result = BuildLoadGlobal(ic, context, name_index, raw_slot, assembler); | |
| 486 __ SetAccumulator(result); | |
| 487 __ Dispatch(); | |
| 488 } | 533 } |
| 489 | 534 |
| 490 // LdaGlobalInsideTypeof <name_index> <slot> | 535 // LdaGlobalInsideTypeof <name_index> <slot> |
| 491 // | 536 // |
| 492 // Load the global with name in constant pool entry <name_index> into the | 537 // Load the global with name in constant pool entry <name_index> into the |
| 493 // accumulator using FeedBackVector slot <slot> inside of a typeof. | 538 // accumulator using FeedBackVector slot <slot> inside of a typeof. |
| 494 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { | 539 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { |
| 495 Callable ic = | 540 Node* raw_slot = __ BytecodeOperandIdx(1); |
| 496 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, INSIDE_TYPEOF); | |
| 497 | 541 |
| 498 Node* context = __ GetContext(); | 542 auto gen_name_index = [=]() { return __ BytecodeOperandIdx(0); }; |
| 499 | 543 |
| 500 Node* name_index = __ BytecodeOperandIdx(0); | 544 BuildLoadGlobal(gen_name_index, raw_slot, INSIDE_TYPEOF, assembler); |
| 501 Node* raw_slot = __ BytecodeOperandIdx(1); | |
| 502 Node* result = BuildLoadGlobal(ic, context, name_index, raw_slot, assembler); | |
| 503 __ SetAccumulator(result); | |
| 504 __ Dispatch(); | |
| 505 } | 545 } |
| 506 | 546 |
| 507 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { | 547 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { |
| 508 // Get the global object. | 548 // Get the global object. |
| 509 Node* context = __ GetContext(); | 549 Node* context = __ GetContext(); |
| 510 Node* native_context = __ LoadNativeContext(context); | 550 Node* native_context = __ LoadNativeContext(context); |
| 511 Node* global = | 551 Node* global = |
| 512 __ LoadContextElement(native_context, Context::EXTENSION_INDEX); | 552 __ LoadContextElement(native_context, Context::EXTENSION_INDEX); |
| 513 | 553 |
| 514 // Store the global via the StoreIC. | 554 // 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| | 722 // Lookup the object with the name in constant pool entry |name_index| |
| 683 // dynamically without causing a NoReferenceError. | 723 // dynamically without causing a NoReferenceError. |
| 684 void Interpreter::DoLdaLookupContextSlotInsideTypeof( | 724 void Interpreter::DoLdaLookupContextSlotInsideTypeof( |
| 685 InterpreterAssembler* assembler) { | 725 InterpreterAssembler* assembler) { |
| 686 DoLdaLookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler); | 726 DoLdaLookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler); |
| 687 } | 727 } |
| 688 | 728 |
| 689 void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id, | 729 void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id, |
| 690 InterpreterAssembler* assembler) { | 730 InterpreterAssembler* assembler) { |
| 691 Node* context = __ GetContext(); | 731 Node* context = __ GetContext(); |
| 692 Node* name_index = __ BytecodeOperandIdx(0); | |
| 693 Node* feedback_slot = __ BytecodeOperandIdx(1); | 732 Node* feedback_slot = __ BytecodeOperandIdx(1); |
| 694 Node* depth = __ BytecodeOperandUImm(2); | 733 Node* depth = __ BytecodeOperandUImm(2); |
| 695 | 734 |
| 696 Label slowpath(assembler, Label::kDeferred); | 735 Label slowpath(assembler, Label::kDeferred); |
| 697 | 736 |
| 698 // Check for context extensions to allow the fast path | 737 // Check for context extensions to allow the fast path |
| 699 __ GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath); | 738 __ GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath); |
| 700 | 739 |
| 701 // Fast path does a normal load global | 740 // Fast path does a normal load global |
| 702 { | 741 { |
| 703 Callable ic = CodeFactory::LoadGlobalICInOptimizedCode( | 742 auto gen_name_index = [=]() { return __ BytecodeOperandIdx(0); }; |
| 704 isolate_, function_id == Runtime::kLoadLookupSlotInsideTypeof | 743 |
| 705 ? INSIDE_TYPEOF | 744 TypeofMode typeof_mode = function_id == Runtime::kLoadLookupSlotInsideTypeof |
| 706 : NOT_INSIDE_TYPEOF); | 745 ? INSIDE_TYPEOF |
| 707 Node* result = | 746 : NOT_INSIDE_TYPEOF; |
| 708 BuildLoadGlobal(ic, context, name_index, feedback_slot, assembler); | 747 |
| 709 __ SetAccumulator(result); | 748 BuildLoadGlobal(gen_name_index, feedback_slot, typeof_mode, assembler); |
| 710 __ Dispatch(); | |
| 711 } | 749 } |
| 712 | 750 |
| 713 // Slow path when we have to call out to the runtime | 751 // Slow path when we have to call out to the runtime |
| 714 __ Bind(&slowpath); | 752 __ Bind(&slowpath); |
| 715 { | 753 { |
| 754 Node* name_index = __ BytecodeOperandIdx(0); | |
| 716 Node* name = __ LoadConstantPoolEntry(name_index); | 755 Node* name = __ LoadConstantPoolEntry(name_index); |
| 717 Node* result = __ CallRuntime(function_id, context, name); | 756 Node* result = __ CallRuntime(function_id, context, name); |
| 718 __ SetAccumulator(result); | 757 __ SetAccumulator(result); |
| 719 __ Dispatch(); | 758 __ Dispatch(); |
| 720 } | 759 } |
| 721 } | 760 } |
| 722 | 761 |
| 723 // LdaLookupGlobalSlot <name_index> <feedback_slot> <depth> | 762 // LdaLookupGlobalSlot <name_index> <feedback_slot> <depth> |
| 724 // | 763 // |
| 725 // Lookup the object with the name in constant pool entry |name_index| | 764 // 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, | 3364 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
| 3326 __ SmiTag(new_state)); | 3365 __ SmiTag(new_state)); |
| 3327 __ SetAccumulator(old_state); | 3366 __ SetAccumulator(old_state); |
| 3328 | 3367 |
| 3329 __ Dispatch(); | 3368 __ Dispatch(); |
| 3330 } | 3369 } |
| 3331 | 3370 |
| 3332 } // namespace interpreter | 3371 } // namespace interpreter |
| 3333 } // namespace internal | 3372 } // namespace internal |
| 3334 } // namespace v8 | 3373 } // namespace v8 |
| OLD | NEW |