| Index: src/ia32/macro-assembler-ia32.cc | 
| diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc | 
| index cdcb24246a75e848a59a07b55cea356b28fd4271..4f7a65a425c138cd8bdc950fc6c704edbf3034af 100644 | 
| --- a/src/ia32/macro-assembler-ia32.cc | 
| +++ b/src/ia32/macro-assembler-ia32.cc | 
| @@ -1987,18 +1987,63 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 
| } | 
|  | 
|  | 
| -void MacroAssembler::InvokeCode(const Operand& code, | 
| -                                Register new_target, | 
| -                                const ParameterCount& expected, | 
| -                                const ParameterCount& actual, | 
| -                                InvokeFlag flag, | 
| -                                const CallWrapper& call_wrapper) { | 
| +void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, | 
| +                                             const ParameterCount& expected, | 
| +                                             const ParameterCount& actual) { | 
| +  Label skip_flooding; | 
| +  ExternalReference debug_step_action = | 
| +      ExternalReference::debug_last_step_action_address(isolate()); | 
| +  cmpb(Operand::StaticVariable(debug_step_action), StepIn); | 
| +  j(not_equal, &skip_flooding); | 
| +  { | 
| +    FrameScope frame(this, | 
| +                     has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); | 
| +    if (expected.is_reg()) { | 
| +      SmiTag(expected.reg()); | 
| +      Push(expected.reg()); | 
| +    } | 
| +    if (actual.is_reg()) { | 
| +      SmiTag(actual.reg()); | 
| +      Push(actual.reg()); | 
| +    } | 
| +    if (new_target.is_valid()) { | 
| +      Push(new_target); | 
| +    } | 
| +    Push(fun); | 
| +    Push(fun); | 
| +    CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1); | 
| +    Pop(fun); | 
| +    if (new_target.is_valid()) { | 
| +      Pop(new_target); | 
| +    } | 
| +    if (actual.is_reg()) { | 
| +      Pop(actual.reg()); | 
| +      SmiUntag(actual.reg()); | 
| +    } | 
| +    if (expected.is_reg()) { | 
| +      Pop(expected.reg()); | 
| +      SmiUntag(expected.reg()); | 
| +    } | 
| +  } | 
| +  bind(&skip_flooding); | 
| +} | 
| + | 
| + | 
| +void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, | 
| +                                        const ParameterCount& expected, | 
| +                                        const ParameterCount& actual, | 
| +                                        InvokeFlag flag, | 
| +                                        const CallWrapper& call_wrapper) { | 
| // You can't call a function without a valid frame. | 
| DCHECK(flag == JUMP_FUNCTION || has_frame()); | 
| - | 
| -  // Ensure new target is passed in the correct register. Otherwise clear the | 
| -  // appropriate register in case new target is not given. | 
| +  DCHECK(function.is(edi)); | 
| DCHECK_IMPLIES(new_target.is_valid(), new_target.is(edx)); | 
| + | 
| +  if (call_wrapper.NeedsDebugStepCheck()) { | 
| +    FloodFunctionIfStepping(function, new_target, expected, actual); | 
| +  } | 
| + | 
| +  // Clear the new.target register if not given. | 
| if (!new_target.is_valid()) { | 
| mov(edx, isolate()->factory()->undefined_value()); | 
| } | 
| @@ -2008,6 +2053,10 @@ void MacroAssembler::InvokeCode(const Operand& code, | 
| InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, | 
| Label::kNear, call_wrapper); | 
| if (!definitely_mismatches) { | 
| +    // We call indirectly through the code field in the function to | 
| +    // allow recompilation to take effect without changing any of the | 
| +    // call sites. | 
| +    Operand code = FieldOperand(function, JSFunction::kCodeEntryOffset); | 
| if (flag == CALL_FUNCTION) { | 
| call_wrapper.BeforeCall(CallSize(code)); | 
| call(code); | 
| @@ -2036,8 +2085,7 @@ void MacroAssembler::InvokeFunction(Register fun, | 
| SmiUntag(ebx); | 
|  | 
| ParameterCount expected(ebx); | 
| -  InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), new_target, | 
| -             expected, actual, flag, call_wrapper); | 
| +  InvokeFunctionCode(edi, new_target, expected, actual, flag, call_wrapper); | 
| } | 
|  | 
|  | 
| @@ -2052,8 +2100,7 @@ void MacroAssembler::InvokeFunction(Register fun, | 
| DCHECK(fun.is(edi)); | 
| mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 
|  | 
| -  InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), no_reg, | 
| -             expected, actual, flag, call_wrapper); | 
| +  InvokeFunctionCode(edi, no_reg, expected, actual, flag, call_wrapper); | 
| } | 
|  | 
|  | 
| @@ -2077,8 +2124,7 @@ void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, | 
| // parameter count to avoid emitting code to do the check. | 
| ParameterCount expected(0); | 
| GetBuiltinFunction(edi, native_context_index); | 
| -  InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), no_reg, | 
| -             expected, expected, flag, call_wrapper); | 
| +  InvokeFunctionCode(edi, no_reg, expected, expected, flag, call_wrapper); | 
| } | 
|  | 
|  | 
| @@ -2091,16 +2137,6 @@ void MacroAssembler::GetBuiltinFunction(Register target, | 
| } | 
|  | 
|  | 
| -void MacroAssembler::GetBuiltinEntry(Register target, | 
| -                                     int native_context_index) { | 
| -  DCHECK(!target.is(edi)); | 
| -  // Load the JavaScript builtin function from the builtins object. | 
| -  GetBuiltinFunction(edi, native_context_index); | 
| -  // Load the code entry point from the function into the target register. | 
| -  mov(target, FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 
| -} | 
| - | 
| - | 
| void MacroAssembler::LoadContext(Register dst, int context_chain_length) { | 
| if (context_chain_length > 0) { | 
| // Move up the chain of contexts to the context containing the slot. | 
|  |