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

Side by Side Diff: src/x87/builtins-x87.cc

Issue 1920713002: X87: [interpreter] Heal closures when bytecode array is gone. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 // Open a frame scope to indicate that there is a frame on the stack. The 548 // Open a frame scope to indicate that there is a frame on the stack. The
549 // MANUAL indicates that the scope shouldn't actually generate code to set up 549 // MANUAL indicates that the scope shouldn't actually generate code to set up
550 // the frame (that is done below). 550 // the frame (that is done below).
551 FrameScope frame_scope(masm, StackFrame::MANUAL); 551 FrameScope frame_scope(masm, StackFrame::MANUAL);
552 __ push(ebp); // Caller's frame pointer. 552 __ push(ebp); // Caller's frame pointer.
553 __ mov(ebp, esp); 553 __ mov(ebp, esp);
554 __ push(esi); // Callee's context. 554 __ push(esi); // Callee's context.
555 __ push(edi); // Callee's JS function. 555 __ push(edi); // Callee's JS function.
556 __ push(edx); // Callee's new target. 556 __ push(edx); // Callee's new target.
557 557
558 // Get the bytecode array from the function object and load the pointer to the 558 // Get the bytecode array from the function object (or from the DebugInfo if
559 // first entry into edi (InterpreterBytecodeRegister). 559 // it is present) and load it into kInterpreterBytecodeArrayRegister.
560 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 560 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
561
562 Label load_debug_bytecode_array, bytecode_array_loaded; 561 Label load_debug_bytecode_array, bytecode_array_loaded;
563 __ cmp(FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset), 562 __ cmp(FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset),
564 Immediate(DebugInfo::uninitialized())); 563 Immediate(DebugInfo::uninitialized()));
565 __ j(not_equal, &load_debug_bytecode_array); 564 __ j(not_equal, &load_debug_bytecode_array);
566 __ mov(kInterpreterBytecodeArrayRegister, 565 __ mov(kInterpreterBytecodeArrayRegister,
567 FieldOperand(eax, SharedFunctionInfo::kFunctionDataOffset)); 566 FieldOperand(eax, SharedFunctionInfo::kFunctionDataOffset));
568 __ bind(&bytecode_array_loaded); 567 __ bind(&bytecode_array_loaded);
569 568
569 // Check function data field is actually a BytecodeArray object.
570 Label bytecode_array_not_present;
571 __ CompareRoot(kInterpreterBytecodeArrayRegister,
572 Heap::kUndefinedValueRootIndex);
573 __ j(equal, &bytecode_array_not_present);
570 if (FLAG_debug_code) { 574 if (FLAG_debug_code) {
571 // Check function data field is actually a BytecodeArray object.
572 __ AssertNotSmi(kInterpreterBytecodeArrayRegister); 575 __ AssertNotSmi(kInterpreterBytecodeArrayRegister);
573 __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE, 576 __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE,
574 eax); 577 eax);
575 __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); 578 __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
576 } 579 }
577 580
578 // Push bytecode array. 581 // Push bytecode array.
579 __ push(kInterpreterBytecodeArrayRegister); 582 __ push(kInterpreterBytecodeArrayRegister);
580 // Push zero for bytecode array offset. 583 // Push zero for bytecode array offset.
581 __ push(Immediate(0)); 584 __ push(Immediate(0));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 // Even though the first bytecode handler was called, we will never return. 635 // Even though the first bytecode handler was called, we will never return.
633 __ Abort(kUnexpectedReturnFromBytecodeHandler); 636 __ Abort(kUnexpectedReturnFromBytecodeHandler);
634 637
635 // Load debug copy of the bytecode array. 638 // Load debug copy of the bytecode array.
636 __ bind(&load_debug_bytecode_array); 639 __ bind(&load_debug_bytecode_array);
637 Register debug_info = kInterpreterBytecodeArrayRegister; 640 Register debug_info = kInterpreterBytecodeArrayRegister;
638 __ mov(debug_info, FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset)); 641 __ mov(debug_info, FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset));
639 __ mov(kInterpreterBytecodeArrayRegister, 642 __ mov(kInterpreterBytecodeArrayRegister,
640 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); 643 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex));
641 __ jmp(&bytecode_array_loaded); 644 __ jmp(&bytecode_array_loaded);
645
646 // If the bytecode array is no longer present, then the underlying function
647 // has been switched to a different kind of code and we heal the closure by
648 // switching the code entry field over to the new code object as well.
649 __ bind(&bytecode_array_not_present);
650 __ pop(edx); // Callee's new target.
651 __ pop(edi); // Callee's JS function.
652 __ pop(esi); // Callee's context.
653 __ leave(); // Leave the frame so we can tail call.
654 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
655 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset));
656 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
657 __ mov(FieldOperand(edi, JSFunction::kCodeEntryOffset), ecx);
658 __ RecordWriteCodeEntryField(edi, ecx, ebx);
659 __ jmp(ecx);
642 } 660 }
643 661
644 662
645 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { 663 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
646 // The return value is in accumulator, which is already in eax. 664 // The return value is in accumulator, which is already in eax.
647 665
648 // Leave the frame (also dropping the register file). 666 // Leave the frame (also dropping the register file).
649 __ leave(); 667 __ leave();
650 668
651 // Drop receiver + arguments and return. 669 // Drop receiver + arguments and return.
(...skipping 2231 matching lines...) Expand 10 before | Expand all | Expand 10 after
2883 // And "return" to the OSR entry point of the function. 2901 // And "return" to the OSR entry point of the function.
2884 __ ret(0); 2902 __ ret(0);
2885 } 2903 }
2886 2904
2887 2905
2888 #undef __ 2906 #undef __
2889 } // namespace internal 2907 } // namespace internal
2890 } // namespace v8 2908 } // namespace v8
2891 2909
2892 #endif // V8_TARGET_ARCH_X87 2910 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698