Revision: 22914
Author: [email protected]
Date: Wed Aug 6 09:48:04 2014 UTC
Log: Version 3.27.34.12 (merged r22693)
CallIC customization stubs must accept that a vector slot is cleared.
(also x87 and mips ports)
[email protected]
BUG=392114
Review URL: https://codereview.chromium.org/443903002
http://code.google.com/p/v8/source/detail?r=22914
Added:
/branches/3.27/test/mjsunit/regress/regress-392114.js
Modified:
/branches/3.27/src/arm/code-stubs-arm.cc
/branches/3.27/src/arm64/code-stubs-arm64.cc
/branches/3.27/src/ia32/code-stubs-ia32.cc
/branches/3.27/src/ic.cc
/branches/3.27/src/mips/code-stubs-mips.cc
/branches/3.27/src/version.cc
/branches/3.27/src/x64/code-stubs-x64.cc
/branches/3.27/src/x87/code-stubs-x87.cc
=======================================
--- /dev/null
+++ /branches/3.27/test/mjsunit/regress/regress-392114.js Wed Aug 6
09:48:04 2014 UTC
@@ -0,0 +1,66 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+Debug = debug.Debug;
+
+function dummy(x) {
+ return x + 100;
+}
+
+function create_closure() {
+ var f = function(arg) {
+ if (arg) { %DeoptimizeFunction(f); }
+ var a = Array(10);
+ for (var i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ }
+ return f;
+}
+
+var c = create_closure();
+c();
+
+// c CallIC state now has custom Array handler installed.
+
+// Turn on the debugger.
+Debug.setListener(function () {});
+
+var d = create_closure();
+%OptimizeFunctionOnNextCall(d);
+// Thanks to the debugger, we recreate the full code too. We deopt and run
+// it, stomping on the unexpected AllocationSite in the type vector slot.
+d(true);
+
+// CallIC in c misinterprets type vector slot contents as an
AllocationSite,
+// corrupting the heap.
+c();
+
+// CallIC MISS - crash due to corruption.
+dummy();
=======================================
--- /branches/3.27/src/arm/code-stubs-arm.cc Wed Jun 18 14:15:57 2014 UTC
+++ /branches/3.27/src/arm/code-stubs-arm.cc Wed Aug 6 09:48:04 2014 UTC
@@ -3081,9 +3081,14 @@
__ mov(r0, Operand(arg_count()));
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
- __ ldr(r2, FieldMemOperand(r4, FixedArray::kHeaderSize));
- // Verify that r2 contains an AllocationSite
- __ AssertUndefinedOrAllocationSite(r2, r4);
+ __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
+
+ // Verify that r4 contains an AllocationSite
+ __ ldr(r5, FieldMemOperand(r4, HeapObject::kMapOffset));
+ __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
+ __ b(ne, &miss);
+
+ __ mov(r2, r4);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
@@ -3150,7 +3155,11 @@
__ b(eq, &miss);
if (!FLAG_trace_ic) {
- // We are going megamorphic, and we don't want to visit the runtime.
+ // We are going megamorphic. If the feedback is a JSFunction, it is
fine
+ // to handle it here. More complex cases are dealt with in the runtime.
+ __ AssertNotSmi(r4);
+ __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
+ __ b(ne, &miss);
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
__ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
__ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
=======================================
--- /branches/3.27/src/arm64/code-stubs-arm64.cc Wed Jun 18 14:15:57 2014
UTC
+++ /branches/3.27/src/arm64/code-stubs-arm64.cc Wed Aug 6 09:48:04 2014
UTC
@@ -3374,15 +3374,19 @@
__ Cmp(function, scratch);
__ B(ne, &miss);
- Register allocation_site = feedback_vector;
__ Mov(x0, Operand(arg_count()));
__ Add(scratch, feedback_vector,
Operand::UntagSmiAndScale(index, kPointerSizeLog2));
- __ Ldr(allocation_site, FieldMemOperand(scratch,
FixedArray::kHeaderSize));
+ __ Ldr(scratch, FieldMemOperand(scratch, FixedArray::kHeaderSize));
- // Verify that x2 contains an AllocationSite
- __ AssertUndefinedOrAllocationSite(allocation_site, scratch);
+ // Verify that scratch contains an AllocationSite
+ Register map = x5;
+ __ Ldr(map, FieldMemOperand(scratch, HeapObject::kMapOffset));
+ __ JumpIfNotRoot(map, Heap::kAllocationSiteMapRootIndex, &miss);
+
+ Register allocation_site = feedback_vector;
+ __ Mov(allocation_site, scratch);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
@@ -3458,7 +3462,10 @@
__ JumpIfRoot(x4, Heap::kUninitializedSymbolRootIndex, &miss);
if (!FLAG_trace_ic) {
- // We are going megamorphic, and we don't want to visit the runtime.
+ // We are going megamorphic. If the feedback is a JSFunction, it is
fine
+ // to handle it here. More complex cases are dealt with in the runtime.
+ __ AssertNotSmi(x4);
+ __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss);
__ Add(x4, feedback_vector,
Operand::UntagSmiAndScale(index, kPointerSizeLog2));
__ LoadRoot(x5, Heap::kMegamorphicSymbolRootIndex);
=======================================
--- /branches/3.27/src/ia32/code-stubs-ia32.cc Wed Jun 18 14:15:57 2014 UTC
+++ /branches/3.27/src/ia32/code-stubs-ia32.cc Wed Aug 6 09:48:04 2014 UTC
@@ -2484,10 +2484,16 @@
__ j(not_equal, &miss);
__ mov(eax, arg_count());
- __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
+ __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize));
+
// Verify that ecx contains an AllocationSite
- __ AssertUndefinedOrAllocationSite(ebx);
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
+ factory->allocation_site_map());
+ __ j(not_equal, &miss);
+
+ __ mov(ebx, ecx);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
@@ -2558,7 +2564,11 @@
__ j(equal, &miss);
if (!FLAG_trace_ic) {
- // We are going megamorphic, and we don't want to visit the runtime.
+ // We are going megamorphic. If the feedback is a JSFunction, it is
fine
+ // to handle it here. More complex cases are dealt with in the runtime.
+ __ AssertNotSmi(ecx);
+ __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
+ __ j(not_equal, &miss);
__ mov(FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize),
Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
=======================================
--- /branches/3.27/src/ic.cc Mon Jun 16 00:04:47 2014 UTC
+++ /branches/3.27/src/ic.cc Wed Aug 6 09:48:04 2014 UTC
@@ -1855,8 +1855,13 @@
isolate()->context()->native_context()->array_function(), isolate());
if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) {
// Alter the slot.
- Handle<AllocationSite> new_site =
isolate()->factory()->NewAllocationSite();
- vector->set(slot->value(), *new_site);
+ Object* feedback = vector->get(slot->value());
+ if (!feedback->IsAllocationSite()) {
+ Handle<AllocationSite> new_site =
+ isolate()->factory()->NewAllocationSite();
+ vector->set(slot->value(), *new_site);
+ }
+
CallIC_ArrayStub stub(isolate(), state);
set_target(*stub.GetCode());
Handle<String> name;
@@ -1896,6 +1901,9 @@
State state(target()->extra_ic_state());
Object* feedback = vector->get(slot->value());
+ // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
+ ASSERT(!feedback->IsSmi());
+
if (feedback->IsJSFunction() || !function->IsJSFunction()) {
// We are going generic.
vector->set(slot->value(),
@@ -1904,9 +1912,14 @@
TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
} else {
- // If we came here feedback must be the uninitialized sentinel,
- // and we are going monomorphic.
- ASSERT(feedback ==
*TypeFeedbackInfo::UninitializedSentinel(isolate()));
+ // The feedback is either uninitialized or an allocation site.
+ // It might be an allocation site because if we re-compile the full
code
+ // to add deoptimization support, we call with the default call-ic, and
+ // merely need to patch the target to match the feedback.
+ // TODO(mvstanton): the better approach is to dispense with patching
+ // altogether, which is in progress.
+ ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate())
||
+ feedback->IsAllocationSite());
// Do we want to install a custom handler?
if (FLAG_use_ic &&
=======================================
--- /branches/3.27/src/mips/code-stubs-mips.cc Wed Jun 18 14:15:57 2014 UTC
+++ /branches/3.27/src/mips/code-stubs-mips.cc Wed Aug 6 09:48:04 2014 UTC
@@ -3240,9 +3240,14 @@
__ li(a0, Operand(arg_count()));
__ sll(at, a3, kPointerSizeLog2 - kSmiTagSize);
__ Addu(at, a2, Operand(at));
- __ lw(a2, FieldMemOperand(at, FixedArray::kHeaderSize));
- // Verify that a2 contains an AllocationSite
- __ AssertUndefinedOrAllocationSite(a2, at);
+ __ lw(t0, FieldMemOperand(at, FixedArray::kHeaderSize));
+
+ // Verify that t0 contains an AllocationSite
+ __ lw(t1, FieldMemOperand(t0, HeapObject::kMapOffset));
+ __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
+ __ Branch(&miss, ne, t1, Operand(at));
+
+ __ mov(a2, t0);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
@@ -3309,7 +3314,11 @@
__ Branch(&miss, eq, t0, Operand(at));
if (!FLAG_trace_ic) {
- // We are going megamorphic, and we don't want to visit the runtime.
+ // We are going megamorphic. If the feedback is a JSFunction, it is
fine
+ // to handle it here. More complex cases are dealt with in the runtime.
+ __ AssertNotSmi(t0);
+ __ GetObjectType(t0, t1, t1);
+ __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE));
__ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
__ Addu(t0, a2, Operand(t0));
__ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
=======================================
--- /branches/3.27/src/version.cc Mon Aug 4 14:18:05 2014 UTC
+++ /branches/3.27/src/version.cc Wed Aug 6 09:48:04 2014 UTC
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 27
#define BUILD_NUMBER 34
-#define PATCH_LEVEL 11
+#define PATCH_LEVEL 12
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.27/src/x64/code-stubs-x64.cc Wed Jun 18 14:15:57 2014 UTC
+++ /branches/3.27/src/x64/code-stubs-x64.cc Wed Aug 6 09:48:04 2014 UTC
@@ -2378,12 +2378,16 @@
__ cmpq(rdi, rcx);
__ j(not_equal, &miss);
- __ movq(rax, Immediate(arg_count()));
- __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size,
+ __ movp(rax, Immediate(arg_count()));
+ __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size,
FixedArray::kHeaderSize));
-
// Verify that ecx contains an AllocationSite
- __ AssertUndefinedOrAllocationSite(rbx);
+ Factory* factory = masm->isolate()->factory();
+ __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset),
+ factory->allocation_site_map());
+ __ j(not_equal, &miss);
+
+ __ movp(rbx, rcx);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
@@ -2457,7 +2461,11 @@
__ j(equal, &miss);
if (!FLAG_trace_ic) {
- // We are going megamorphic, and we don't want to visit the runtime.
+ // We are going megamorphic. If the feedback is a JSFunction, it is
fine
+ // to handle it here. More complex cases are dealt with in the runtime.
+ __ AssertNotSmi(rcx);
+ __ CmpObjectType(rcx, JS_FUNCTION_TYPE, rcx);
+ __ j(not_equal, &miss);
__ Move(FieldOperand(rbx, rdx, times_pointer_size,
FixedArray::kHeaderSize),
TypeFeedbackInfo::MegamorphicSentinel(isolate));
=======================================
--- /branches/3.27/src/x87/code-stubs-x87.cc Wed Jun 18 14:15:57 2014 UTC
+++ /branches/3.27/src/x87/code-stubs-x87.cc Wed Aug 6 09:48:04 2014 UTC
@@ -2166,10 +2166,16 @@
__ j(not_equal, &miss);
__ mov(eax, arg_count());
- __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
+ __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize));
+
// Verify that ecx contains an AllocationSite
- __ AssertUndefinedOrAllocationSite(ebx);
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
+ factory->allocation_site_map());
+ __ j(not_equal, &miss);
+
+ __ mov(ebx, ecx);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
@@ -2240,7 +2246,11 @@
__ j(equal, &miss);
if (!FLAG_trace_ic) {
- // We are going megamorphic, and we don't want to visit the runtime.
+ // We are going megamorphic. If the feedback is a JSFunction, it is
fine
+ // to handle it here. More complex cases are dealt with in the runtime.
+ __ AssertNotSmi(ecx);
+ __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
+ __ j(not_equal, &miss);
__ mov(FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize),
Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.