Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: src/interpreter/interpreter.cc

Issue 2347143002: [interpreter] Add fast path for dynamic global lookups (Closed)
Patch Set: Fix bytecode operand documentation Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/interpreter.h ('k') | test/cctest/compiler/test-run-bytecode-graph-builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 // 414 //
415 // Stores the value of register <src> to register <dst>. 415 // Stores the value of register <src> to register <dst>.
416 void Interpreter::DoMov(InterpreterAssembler* assembler) { 416 void Interpreter::DoMov(InterpreterAssembler* assembler) {
417 Node* src_index = __ BytecodeOperandReg(0); 417 Node* src_index = __ BytecodeOperandReg(0);
418 Node* src_value = __ LoadRegister(src_index); 418 Node* src_value = __ LoadRegister(src_index);
419 Node* dst_index = __ BytecodeOperandReg(1); 419 Node* dst_index = __ BytecodeOperandReg(1);
420 __ StoreRegister(src_value, dst_index); 420 __ StoreRegister(src_value, dst_index);
421 __ Dispatch(); 421 __ Dispatch();
422 } 422 }
423 423
424 Node* Interpreter::BuildLoadGlobal(Callable ic, 424 Node* Interpreter::BuildLoadGlobal(Callable ic, Node* context,
425 Node* feedback_slot,
425 InterpreterAssembler* assembler) { 426 InterpreterAssembler* assembler) {
426 typedef LoadGlobalWithVectorDescriptor Descriptor; 427 typedef LoadGlobalWithVectorDescriptor Descriptor;
427 // Get the global object.
428 Node* context = __ GetContext();
429 428
430 // Load the global via the LoadGlobalIC. 429 // Load the global via the LoadGlobalIC.
431 Node* code_target = __ HeapConstant(ic.code()); 430 Node* code_target = __ HeapConstant(ic.code());
432 Node* raw_slot = __ BytecodeOperandIdx(0); 431 Node* smi_slot = __ SmiTag(feedback_slot);
433 Node* smi_slot = __ SmiTag(raw_slot);
434 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 432 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
435 return __ CallStub(ic.descriptor(), code_target, context, 433 return __ CallStub(ic.descriptor(), code_target, context,
436 Arg(Descriptor::kSlot, smi_slot), 434 Arg(Descriptor::kSlot, smi_slot),
437 Arg(Descriptor::kVector, type_feedback_vector)); 435 Arg(Descriptor::kVector, type_feedback_vector));
438 } 436 }
439 437
440 // LdaGlobal <slot> 438 // LdaGlobal <slot>
441 // 439 //
442 // Load the global with name in constant pool entry <name_index> into the 440 // Load the global with name in constant pool entry <name_index> into the
443 // accumulator using FeedBackVector slot <slot> outside of a typeof. 441 // accumulator using FeedBackVector slot <slot> outside of a typeof.
444 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { 442 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) {
445 Callable ic = 443 Callable ic =
446 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF); 444 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF);
447 Node* result = BuildLoadGlobal(ic, assembler); 445
446 Node* context = __ GetContext();
447
448 Node* raw_slot = __ BytecodeOperandIdx(0);
449 Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler);
448 __ SetAccumulator(result); 450 __ SetAccumulator(result);
449 __ Dispatch(); 451 __ Dispatch();
450 } 452 }
451 453
452 // LdrGlobal <slot> <reg> 454 // LdrGlobal <slot> <reg>
453 // 455 //
454 // Load the global with name in constant pool entry <name_index> into 456 // Load the global with name in constant pool entry <name_index> into
455 // register <reg> using FeedBackVector slot <slot> outside of a typeof. 457 // register <reg> using FeedBackVector slot <slot> outside of a typeof.
456 void Interpreter::DoLdrGlobal(InterpreterAssembler* assembler) { 458 void Interpreter::DoLdrGlobal(InterpreterAssembler* assembler) {
457 Callable ic = 459 Callable ic =
458 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF); 460 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF);
459 Node* result = BuildLoadGlobal(ic, assembler); 461
462 Node* context = __ GetContext();
463
464 Node* raw_slot = __ BytecodeOperandIdx(0);
465 Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler);
460 Node* destination = __ BytecodeOperandReg(1); 466 Node* destination = __ BytecodeOperandReg(1);
461 __ StoreRegister(result, destination); 467 __ StoreRegister(result, destination);
462 __ Dispatch(); 468 __ Dispatch();
463 } 469 }
464 470
465 // LdaGlobalInsideTypeof <slot> 471 // LdaGlobalInsideTypeof <slot>
466 // 472 //
467 // Load the global with name in constant pool entry <name_index> into the 473 // Load the global with name in constant pool entry <name_index> into the
468 // accumulator using FeedBackVector slot <slot> inside of a typeof. 474 // accumulator using FeedBackVector slot <slot> inside of a typeof.
469 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { 475 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) {
470 Callable ic = 476 Callable ic =
471 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, INSIDE_TYPEOF); 477 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, INSIDE_TYPEOF);
472 Node* result = BuildLoadGlobal(ic, assembler); 478
479 Node* context = __ GetContext();
480
481 Node* raw_slot = __ BytecodeOperandIdx(0);
482 Node* result = BuildLoadGlobal(ic, context, raw_slot, assembler);
473 __ SetAccumulator(result); 483 __ SetAccumulator(result);
474 __ Dispatch(); 484 __ Dispatch();
475 } 485 }
476 486
477 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { 487 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) {
478 typedef StoreWithVectorDescriptor Descriptor; 488 typedef StoreWithVectorDescriptor Descriptor;
479 // Get the global object. 489 // Get the global object.
480 Node* context = __ GetContext(); 490 Node* context = __ GetContext();
481 Node* native_context = 491 Node* native_context =
482 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); 492 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 Node* context = __ LoadRegister(reg_index); 566 Node* context = __ LoadRegister(reg_index);
557 Node* slot_index = __ BytecodeOperandIdx(1); 567 Node* slot_index = __ BytecodeOperandIdx(1);
558 Node* depth = __ BytecodeOperandUImm(2); 568 Node* depth = __ BytecodeOperandUImm(2);
559 Node* slot_context = __ GetContextAtDepth(context, depth); 569 Node* slot_context = __ GetContextAtDepth(context, depth);
560 __ StoreContextSlot(slot_context, slot_index, value); 570 __ StoreContextSlot(slot_context, slot_index, value);
561 __ Dispatch(); 571 __ Dispatch();
562 } 572 }
563 573
564 void Interpreter::DoLdaLookupSlot(Runtime::FunctionId function_id, 574 void Interpreter::DoLdaLookupSlot(Runtime::FunctionId function_id,
565 InterpreterAssembler* assembler) { 575 InterpreterAssembler* assembler) {
566 Node* index = __ BytecodeOperandIdx(0); 576 Node* name_index = __ BytecodeOperandIdx(0);
567 Node* name = __ LoadConstantPoolEntry(index); 577 Node* name = __ LoadConstantPoolEntry(name_index);
568 Node* context = __ GetContext(); 578 Node* context = __ GetContext();
569 Node* result = __ CallRuntime(function_id, context, name); 579 Node* result = __ CallRuntime(function_id, context, name);
570 __ SetAccumulator(result); 580 __ SetAccumulator(result);
571 __ Dispatch(); 581 __ Dispatch();
572 } 582 }
573 583
574 // LdaLookupSlot <name_index> 584 // LdaLookupSlot <name_index>
575 // 585 //
576 // Lookup the object with the name in constant pool entry |name_index| 586 // Lookup the object with the name in constant pool entry |name_index|
577 // dynamically. 587 // dynamically.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 637
628 // LdaLookupSlotInsideTypeof <name_index> 638 // LdaLookupSlotInsideTypeof <name_index>
629 // 639 //
630 // Lookup the object with the name in constant pool entry |name_index| 640 // Lookup the object with the name in constant pool entry |name_index|
631 // dynamically without causing a NoReferenceError. 641 // dynamically without causing a NoReferenceError.
632 void Interpreter::DoLdaLookupContextSlotInsideTypeof( 642 void Interpreter::DoLdaLookupContextSlotInsideTypeof(
633 InterpreterAssembler* assembler) { 643 InterpreterAssembler* assembler) {
634 DoLdaLookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler); 644 DoLdaLookupContextSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
635 } 645 }
636 646
647 void Interpreter::DoLdaLookupGlobalSlot(Runtime::FunctionId function_id,
648 InterpreterAssembler* assembler) {
649 Node* context = __ GetContext();
650 Node* name_index = __ BytecodeOperandIdx(0);
651 Node* feedback_slot = __ BytecodeOperandIdx(1);
652 Node* depth = __ BytecodeOperandUImm(2);
653
654 Label slowpath(assembler, Label::kDeferred);
655
656 // Check for context extensions to allow the fast path
657 __ GotoIfHasContextExtensionUpToDepth(context, depth, &slowpath);
658
659 // Fast path does a normal load global
660 {
661 Callable ic = CodeFactory::LoadGlobalICInOptimizedCode(
662 isolate_, function_id == Runtime::kLoadLookupSlotInsideTypeof
663 ? INSIDE_TYPEOF
664 : NOT_INSIDE_TYPEOF);
665 Node* result = BuildLoadGlobal(ic, context, feedback_slot, assembler);
666 __ SetAccumulator(result);
667 __ Dispatch();
668 }
669
670 // Slow path when we have to call out to the runtime
671 __ Bind(&slowpath);
672 {
673 Node* name = __ LoadConstantPoolEntry(name_index);
674 Node* result = __ CallRuntime(function_id, context, name);
675 __ SetAccumulator(result);
676 __ Dispatch();
677 }
678 }
679
680 // LdaLookupGlobalSlot <name_index> <feedback_slot> <depth>
681 //
682 // Lookup the object with the name in constant pool entry |name_index|
683 // dynamically.
684 void Interpreter::DoLdaLookupGlobalSlot(InterpreterAssembler* assembler) {
685 DoLdaLookupGlobalSlot(Runtime::kLoadLookupSlot, assembler);
686 }
687
688 // LdaLookupGlobalSlotInsideTypeof <name_index> <feedback_slot> <depth>
689 //
690 // Lookup the object with the name in constant pool entry |name_index|
691 // dynamically without causing a NoReferenceError.
692 void Interpreter::DoLdaLookupGlobalSlotInsideTypeof(
693 InterpreterAssembler* assembler) {
694 DoLdaLookupGlobalSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
695 }
696
637 void Interpreter::DoStaLookupSlot(LanguageMode language_mode, 697 void Interpreter::DoStaLookupSlot(LanguageMode language_mode,
638 InterpreterAssembler* assembler) { 698 InterpreterAssembler* assembler) {
639 Node* value = __ GetAccumulator(); 699 Node* value = __ GetAccumulator();
640 Node* index = __ BytecodeOperandIdx(0); 700 Node* index = __ BytecodeOperandIdx(0);
641 Node* name = __ LoadConstantPoolEntry(index); 701 Node* name = __ LoadConstantPoolEntry(index);
642 Node* context = __ GetContext(); 702 Node* context = __ GetContext();
643 Node* result = __ CallRuntime(is_strict(language_mode) 703 Node* result = __ CallRuntime(is_strict(language_mode)
644 ? Runtime::kStoreLookupSlot_Strict 704 ? Runtime::kStoreLookupSlot_Strict
645 : Runtime::kStoreLookupSlot_Sloppy, 705 : Runtime::kStoreLookupSlot_Sloppy,
646 context, name, value); 706 context, name, value);
(...skipping 1866 matching lines...) Expand 10 before | Expand all | Expand 10 after
2513 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, 2573 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset,
2514 __ SmiTag(new_state)); 2574 __ SmiTag(new_state));
2515 __ SetAccumulator(old_state); 2575 __ SetAccumulator(old_state);
2516 2576
2517 __ Dispatch(); 2577 __ Dispatch();
2518 } 2578 }
2519 2579
2520 } // namespace interpreter 2580 } // namespace interpreter
2521 } // namespace internal 2581 } // namespace internal
2522 } // namespace v8 2582 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/interpreter.h ('k') | test/cctest/compiler/test-run-bytecode-graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698