Index: bleeding_edge/src/x64/stub-cache-x64.cc |
=================================================================== |
--- bleeding_edge/src/x64/stub-cache-x64.cc (revision 3479) |
+++ bleeding_edge/src/x64/stub-cache-x64.cc (working copy) |
@@ -956,9 +956,25 @@ |
__ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); |
// Check that the cell contains the same function. |
- __ Cmp(rdi, Handle<JSFunction>(function)); |
- __ j(not_equal, &miss); |
+ 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. |
+ __ JumpIfSmi(rdi, &miss); |
+ __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
+ __ j(not_equal, &miss); |
+ // Check the shared function info. Make sure it hasn't changed. |
+ __ Move(rcx, Handle<SharedFunctionInfo>(function->shared())); |
+ __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rcx); |
+ __ j(not_equal, &miss); |
+ } else { |
+ __ Cmp(rdi, Handle<JSFunction>(function)); |
+ __ j(not_equal, &miss); |
+ } |
+ |
// Patch the receiver on the stack with the global proxy. |
if (object->IsGlobalObject()) { |
__ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |