Chromium Code Reviews| 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); |
| } |