Index: src/ia32/builtins-ia32.cc |
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc |
index 34dd73c33159338813c3f3a942430826e60d38e0..ad9d8764d70ff322076208beed56e852ead6d75f 100644 |
--- a/src/ia32/builtins-ia32.cc |
+++ b/src/ia32/builtins-ia32.cc |
@@ -554,11 +554,10 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
__ push(edi); // Callee's JS function. |
__ push(edx); // Callee's new target. |
- // Get the bytecode array from the function object and load the pointer to the |
- // first entry into edi (InterpreterBytecodeRegister). |
- __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
- |
+ // Get the bytecode array from the function object (or from the DebugInfo if |
+ // it is present) and load it into edi (InterpreterBytecodeArrayRegister). |
Label load_debug_bytecode_array, bytecode_array_loaded; |
+ __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
__ cmp(FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset), |
Immediate(DebugInfo::uninitialized())); |
__ j(not_equal, &load_debug_bytecode_array); |
@@ -566,13 +565,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
FieldOperand(eax, SharedFunctionInfo::kFunctionDataOffset)); |
__ bind(&bytecode_array_loaded); |
- if (FLAG_debug_code) { |
- // Check function data field is actually a BytecodeArray object. |
- __ AssertNotSmi(kInterpreterBytecodeArrayRegister); |
- __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE, |
- eax); |
- __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
- } |
+ // Check function data field is actually a BytecodeArray object. |
+ Label bytecode_array_not_present; |
+ __ JumpIfSmi(kInterpreterBytecodeArrayRegister, &bytecode_array_not_present); |
rmcilroy
2016/04/21 15:16:02
Maybe you could just compare with undefined to che
Michael Starzinger
2016/04/21 15:43:08
Done. Good point.
|
+ __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE, eax); |
+ __ j(not_equal, &bytecode_array_not_present); |
// Push bytecode array. |
__ push(kInterpreterBytecodeArrayRegister); |
@@ -638,6 +635,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
__ mov(kInterpreterBytecodeArrayRegister, |
FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); |
__ jmp(&bytecode_array_loaded); |
+ |
+ // If the bytecode array is no longer present, then the underlying function |
+ // has been switched to a different kind of code and we heal the closure by |
+ // switching the code entry field over to the new code object as well. |
+ __ bind(&bytecode_array_not_present); |
+ __ pop(edx); // Callee's new target. |
+ __ pop(edi); // Callee's JS function. |
+ __ pop(esi); // Callee's context. |
+ __ leave(); // Leave the frame so we can tail call. |
+ __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
+ __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset)); |
+ __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
+ __ mov(FieldOperand(edi, JSFunction::kCodeEntryOffset), ecx); |
+ __ RecordWriteCodeEntryField(edi, ecx, ebx); |
+ __ jmp(ecx); |
} |