| Index: bleeding_edge/src/ia32/stub-cache-ia32.cc
|
| ===================================================================
|
| --- bleeding_edge/src/ia32/stub-cache-ia32.cc (revision 3473)
|
| +++ bleeding_edge/src/ia32/stub-cache-ia32.cc (working copy)
|
| @@ -1154,9 +1154,26 @@
|
| __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset));
|
|
|
| // Check that the cell contains the same function.
|
| - __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function)));
|
| - __ j(not_equal, &miss, not_taken);
|
| + if (Heap::InNewSpace(function)) {
|
| + // We can't embed a pointer to a function in new space so we have
|
| + // to verify that the shared function info is unchanged. This has
|
| + // the nice side effect that multiple closures based on the same
|
| + // function can all use this call IC. Before we load through the
|
| + // function, we have to verify that it still is a function.
|
| + __ test(edi, Immediate(kSmiTagMask));
|
| + __ j(zero, &miss, not_taken);
|
| + __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
|
| + __ j(not_equal, &miss, not_taken);
|
|
|
| + // Check the shared function info. Make sure it hasn't changed.
|
| + __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
|
| + Immediate(Handle<SharedFunctionInfo>(function->shared())));
|
| + __ j(not_equal, &miss, not_taken);
|
| + } else {
|
| + __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function)));
|
| + __ j(not_equal, &miss, not_taken);
|
| + }
|
| +
|
| // Patch the receiver on the stack with the global proxy.
|
| if (object->IsGlobalObject()) {
|
| __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
|
|
|