Revision: 12607
Author: [email protected]
Date: Tue Sep 25 10:29:23 2012
Log: Merged r12531, r12562, r12563 into 3.12 branch.
Fix casting error for receiver of interceptors.
Fix LBoundsCheck on x64 to handle (stack slot + constant) correctly
Fix missing slot recodring during clearing of CallICs.
BUG=chromium:149912,150729,chromium:144230
[email protected]
Review URL: https://codereview.chromium.org/10993011
http://code.google.com/p/v8/source/detail?r=12607
Added:
/branches/3.12/test/mjsunit/regress/regress-crbug-150729.js
Modified:
/branches/3.12/src/ic-inl.h
/branches/3.12/src/objects.cc
/branches/3.12/src/objects.h
/branches/3.12/src/version.cc
/branches/3.12/src/x64/lithium-codegen-x64.cc
/branches/3.12/test/cctest/test-api.cc
/branches/3.12/test/cctest/test-heap.cc
=======================================
--- /dev/null
+++ /branches/3.12/test/mjsunit/regress/regress-crbug-150729.js Tue Sep 25
10:29:23 2012
@@ -0,0 +1,39 @@
+// Copyright 2012 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: --allow-natives-syntax
+
+var t = 0;
+function burn() {
+ i = [t, 1];
+ var M = [i[0], Math.cos(t) + i[7074959]];
+ t += .05;
+}
+for (var j = 0; j < 5; j++) {
+ if (j == 2) %OptimizeFunctionOnNextCall(burn);
+ burn();
+}
=======================================
--- /branches/3.12/src/ic-inl.h Tue Feb 21 02:08:21 2012
+++ /branches/3.12/src/ic-inl.h Tue Sep 25 10:29:23 2012
@@ -79,6 +79,7 @@
void IC::SetTargetAtAddress(Address address, Code* target) {
ASSERT(target->is_inline_cache_stub() || target->is_compare_ic_stub());
+ Heap* heap = target->GetHeap();
Code* old_target = GetTargetAtAddress(address);
#ifdef DEBUG
// STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark
@@ -90,8 +91,15 @@
}
#endif
Assembler::set_target_address_at(address, target->instruction_start());
- target->GetHeap()->incremental_marking()->RecordCodeTargetPatch(address,
- target);
+ if (heap->gc_state() == Heap::MARK_COMPACT &&
+ heap->mark_compact_collector()->is_compacting()) {
+ Code* host = heap->isolate()->inner_pointer_to_code_cache()->
+ GcSafeFindCodeForInnerPointer(address);
+ RelocInfo rinfo(address, RelocInfo::CODE_TARGET, 0, host);
+ heap->mark_compact_collector()->RecordRelocSlot(&rinfo, target);
+ } else {
+ heap->incremental_marking()->RecordCodeTargetPatch(address, target);
+ }
PostPatching(address, target, old_target);
}
=======================================
--- /branches/3.12/src/objects.cc Wed Sep 5 13:04:15 2012
+++ /branches/3.12/src/objects.cc Tue Sep 25 10:29:23 2012
@@ -650,11 +650,9 @@
receiver, result->GetCallbackObject(), name);
case HANDLER:
return result->proxy()->GetPropertyWithHandler(receiver, name);
- case INTERCEPTOR: {
- JSObject* recvr = JSObject::cast(receiver);
+ case INTERCEPTOR:
return result->holder()->GetPropertyWithInterceptor(
- recvr, name, attributes);
- }
+ receiver, name, attributes);
case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
@@ -10239,7 +10237,7 @@
MaybeObject* JSObject::GetPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
@@ -10257,7 +10255,7 @@
MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
@@ -10271,13 +10269,13 @@
MaybeObject* JSObject::GetPropertyWithInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes) {
Isolate* isolate = GetIsolate();
InterceptorInfo* interceptor = GetNamedInterceptor();
HandleScope scope(isolate);
- Handle<JSReceiver> receiver_handle(receiver);
+ Handle<Object> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
Handle<String> name_handle(name);
=======================================
--- /branches/3.12/src/objects.h Tue Aug 21 01:56:54 2012
+++ /branches/3.12/src/objects.h Tue Sep 25 10:29:23 2012
@@ -1683,15 +1683,15 @@
String* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes);
=======================================
--- /branches/3.12/src/version.cc Fri Sep 21 03:40:37 2012
+++ /branches/3.12/src/version.cc Tue Sep 25 10:29:23 2012
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 12
#define BUILD_NUMBER 19
-#define PATCH_LEVEL 12
+#define PATCH_LEVEL 13
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.12/src/x64/lithium-codegen-x64.cc Wed Aug 1 04:14:42 2012
+++ /branches/3.12/src/x64/lithium-codegen-x64.cc Tue Sep 25 10:29:23 2012
@@ -3643,11 +3643,17 @@
__ cmpq(reg, reg2);
}
} else {
+ Operand length = ToOperand(instr->length());
if (instr->index()->IsConstantOperand()) {
- __ cmpq(ToOperand(instr->length()),
-
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+ int constant_index =
+ ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->hydrogen()->length()->representation().IsTagged()) {
+ __ Cmp(length, Smi::FromInt(constant_index));
+ } else {
+ __ cmpq(length, Immediate(constant_index));
+ }
} else {
- __ cmpq(ToOperand(instr->length()), ToRegister(instr->index()));
+ __ cmpq(length, ToRegister(instr->index()));
}
}
DeoptimizeIf(below_equal, instr->environment());
=======================================
--- /branches/3.12/test/cctest/test-api.cc Mon Sep 17 01:14:05 2012
+++ /branches/3.12/test/cctest/test-api.cc Tue Sep 25 10:29:23 2012
@@ -17182,3 +17182,13 @@
CompileRun("try { throw new Error(); } finally { gc(); }");
CHECK(try_catch.HasCaught());
}
+
+
+THREADED_TEST(Regress149912) {
+ v8::HandleScope scope;
+ LocalContext context;
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
+ context->Global()->Set(v8_str("Bug"), templ->GetFunction());
+ CompileRun("Number.prototype.__proto__ = new Bug; var x = 0; x.foo();");
+}
=======================================
--- /branches/3.12/test/cctest/test-heap.cc Wed Aug 1 04:14:42 2012
+++ /branches/3.12/test/cctest/test-heap.cc Tue Sep 25 10:29:23 2012
@@ -4,10 +4,12 @@
#include "v8.h"
+#include "compilation-cache.h"
#include "execution.h"
#include "factory.h"
#include "macro-assembler.h"
#include "global-handles.h"
+#include "stub-cache.h"
#include "cctest.h"
using namespace v8::internal;
@@ -2025,3 +2027,62 @@
CHECK_LE(hashtable->SizeFor(hashtable->length()), 13 * kPointerSize);
}
}
+
+
+TEST(Regression144230) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ // First make sure that the uninitialized CallIC stub is on a single page
+ // that will later be selected as an evacuation candidate.
+ {
+ v8::HandleScope inner_scope;
+ AlwaysAllocateScope always_allocate;
+ SimulateFullSpace(HEAP->code_space());
+ ISOLATE->stub_cache()->ComputeCallInitialize(9,
RelocInfo::CODE_TARGET);
+ }
+
+ // Second compile a CallIC and execute it once so that it gets patched to
+ // the pre-monomorphic stub. These code objects are on yet another page.
+ {
+ v8::HandleScope inner_scope;
+ AlwaysAllocateScope always_allocate;
+ SimulateFullSpace(HEAP->code_space());
+ CompileRun("var o = { f:function(a,b,c,d,e,f,g,h,i) {}};"
+ "function call() { o.f(1,2,3,4,5,6,7,8,9); };"
+ "call();");
+ }
+
+ // Third we fill up the last page of the code space so that it does not
get
+ // chosen as an evacuation candidate.
+ {
+ v8::HandleScope inner_scope;
+ AlwaysAllocateScope always_allocate;
+ CompileRun("for (var i = 0; i < 2000; i++) {"
+ " eval('function f' + i + '() { return ' + i +'; };' +"
+ " 'f' + i + '();');"
+ "}");
+ }
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+ // Fourth is the tricky part. Make sure the code containing the CallIC is
+ // visited first without clearing the IC. The shared function info is
then
+ // visited later, causing the CallIC to be cleared.
+ Handle<String> name = FACTORY->LookupAsciiSymbol("call");
+ Handle<GlobalObject> global(ISOLATE->context()->global());
+ MaybeObject* maybe_call = global->GetProperty(*name);
+ JSFunction* call = JSFunction::cast(maybe_call->ToObjectChecked());
+ USE(global->SetProperty(*name, Smi::FromInt(0), NONE, kNonStrictMode));
+ ISOLATE->compilation_cache()->Clear();
+ call->shared()->set_ic_age(HEAP->global_ic_age() + 1);
+ Handle<Object> call_code(call->code());
+ Handle<Object> call_function(call);
+
+ // Now we are ready to mess up the heap.
+ HEAP->CollectAllGarbage(Heap::kReduceMemoryFootprintMask);
+
+ // Either heap verification caught the problem already or we go kaboom
once
+ // the CallIC is executed the next time.
+ USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode));
+ CompileRun("call();");
+}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev