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

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

Issue 1904093002: [interpreter] Heal closures when bytecode array is gone. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ported to most architectures. Created 4 years, 8 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 | src/arm64/builtins-arm64.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 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_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.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 974 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 // frames.h for its layout. 985 // frames.h for its layout.
986 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { 986 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
987 ProfileEntryHookStub::MaybeCallEntryHook(masm); 987 ProfileEntryHookStub::MaybeCallEntryHook(masm);
988 988
989 // Open a frame scope to indicate that there is a frame on the stack. The 989 // Open a frame scope to indicate that there is a frame on the stack. The
990 // MANUAL indicates that the scope shouldn't actually generate code to set up 990 // MANUAL indicates that the scope shouldn't actually generate code to set up
991 // the frame (that is done below). 991 // the frame (that is done below).
992 FrameScope frame_scope(masm, StackFrame::MANUAL); 992 FrameScope frame_scope(masm, StackFrame::MANUAL);
993 __ PushStandardFrame(r1); 993 __ PushStandardFrame(r1);
994 994
995 // Get the bytecode array from the function object and load the pointer to the 995 // Get the bytecode array from the function object (or from the DebugInfo if
996 // first entry into kInterpreterBytecodeRegister. 996 // it is present) and load it into kInterpreterBytecodeArrayRegister.
997 __ ldr(r0, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 997 __ ldr(r0, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
998 Register debug_info = kInterpreterBytecodeArrayRegister; 998 Register debug_info = kInterpreterBytecodeArrayRegister;
999 DCHECK(!debug_info.is(r0)); 999 DCHECK(!debug_info.is(r0));
1000 __ ldr(debug_info, FieldMemOperand(r0, SharedFunctionInfo::kDebugInfoOffset)); 1000 __ ldr(debug_info, FieldMemOperand(r0, SharedFunctionInfo::kDebugInfoOffset));
1001 __ cmp(debug_info, Operand(DebugInfo::uninitialized())); 1001 __ cmp(debug_info, Operand(DebugInfo::uninitialized()));
1002 // Load original bytecode array or the debug copy. 1002 // Load original bytecode array or the debug copy.
1003 __ ldr(kInterpreterBytecodeArrayRegister, 1003 __ ldr(kInterpreterBytecodeArrayRegister,
1004 FieldMemOperand(r0, SharedFunctionInfo::kFunctionDataOffset), eq); 1004 FieldMemOperand(r0, SharedFunctionInfo::kFunctionDataOffset), eq);
1005 __ ldr(kInterpreterBytecodeArrayRegister, 1005 __ ldr(kInterpreterBytecodeArrayRegister,
1006 FieldMemOperand(debug_info, DebugInfo::kAbstractCodeIndex), ne); 1006 FieldMemOperand(debug_info, DebugInfo::kAbstractCodeIndex), ne);
1007 1007
1008 // Check function data field is actually a BytecodeArray object.
1009 Label bytecode_array_not_present;
1010 __ CompareRoot(kInterpreterBytecodeArrayRegister,
1011 Heap::kUndefinedValueRootIndex);
1012 __ b(eq, &bytecode_array_not_present);
1008 if (FLAG_debug_code) { 1013 if (FLAG_debug_code) {
1009 // Check function data field is actually a BytecodeArray object.
1010 __ SmiTst(kInterpreterBytecodeArrayRegister); 1014 __ SmiTst(kInterpreterBytecodeArrayRegister);
1011 __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); 1015 __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1012 __ CompareObjectType(kInterpreterBytecodeArrayRegister, r0, no_reg, 1016 __ CompareObjectType(kInterpreterBytecodeArrayRegister, r0, no_reg,
1013 BYTECODE_ARRAY_TYPE); 1017 BYTECODE_ARRAY_TYPE);
1014 __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); 1018 __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1015 } 1019 }
1016 1020
1017 // Push new.target, bytecode array and zero for bytecode array offset. 1021 // Push new.target, bytecode array and zero for bytecode array offset.
1018 __ mov(r0, Operand(0)); 1022 __ mov(r0, Operand(0));
1019 __ Push(r3, kInterpreterBytecodeArrayRegister, r0); 1023 __ Push(r3, kInterpreterBytecodeArrayRegister, r0);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 1063
1060 // Dispatch to the first bytecode handler for the function. 1064 // Dispatch to the first bytecode handler for the function.
1061 __ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister, 1065 __ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
1062 kInterpreterBytecodeOffsetRegister)); 1066 kInterpreterBytecodeOffsetRegister));
1063 __ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL, 1067 __ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
1064 kPointerSizeLog2)); 1068 kPointerSizeLog2));
1065 __ Call(ip); 1069 __ Call(ip);
1066 1070
1067 // Even though the first bytecode handler was called, we will never return. 1071 // Even though the first bytecode handler was called, we will never return.
1068 __ Abort(kUnexpectedReturnFromBytecodeHandler); 1072 __ Abort(kUnexpectedReturnFromBytecodeHandler);
1073
1074 // If the bytecode array is no longer present, then the underlying function
1075 // has been switched to a different kind of code and we heal the closure by
1076 // switching the code entry field over to the new code object as well.
1077 __ bind(&bytecode_array_not_present);
1078 __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1079 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1080 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCodeOffset));
1081 __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1082 __ str(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1083 __ RecordWriteCodeEntryField(r1, r4, r5);
1084 __ Jump(r4);
1069 } 1085 }
1070 1086
1071 1087
1072 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { 1088 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
1073 // The return value is in accumulator, which is already in r0. 1089 // The return value is in accumulator, which is already in r0.
1074 1090
1075 // Leave the frame (also dropping the register file). 1091 // Leave the frame (also dropping the register file).
1076 __ LeaveFrame(StackFrame::JAVA_SCRIPT); 1092 __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1077 1093
1078 // Drop receiver + arguments and return. 1094 // Drop receiver + arguments and return.
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after
2774 } 2790 }
2775 } 2791 }
2776 2792
2777 2793
2778 #undef __ 2794 #undef __
2779 2795
2780 } // namespace internal 2796 } // namespace internal
2781 } // namespace v8 2797 } // namespace v8
2782 2798
2783 #endif // V8_TARGET_ARCH_ARM 2799 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/builtins-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698