Revision: 12716
Author: [email protected]
Date: Fri Oct 12 07:02:49 2012
Log: Merged r12504, r12531, r12562, r12563, r12655 into 3.13 branch.
Fix caching of optimized code for OSR.
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.
Fix slot recording of code target patches.
[email protected]
BUG=v8:2326,chromium:149912,150729,chromium:144230,chromium:152615,chromium:144230
Review URL: https://codereview.chromium.org/11117020
http://code.google.com/p/v8/source/detail?r=12716
Added:
/branches/3.13/test/mjsunit/regress/regress-2326.js
/branches/3.13/test/mjsunit/regress/regress-crbug-150729.js
Modified:
/branches/3.13/src/compiler.cc
/branches/3.13/src/ic-inl.h
/branches/3.13/src/mark-compact.cc
/branches/3.13/src/mark-compact.h
/branches/3.13/src/objects.cc
/branches/3.13/src/objects.h
/branches/3.13/src/version.cc
/branches/3.13/src/x64/lithium-codegen-x64.cc
/branches/3.13/test/cctest/test-api.cc
/branches/3.13/test/cctest/test-heap.cc
=======================================
--- /dev/null
+++ /branches/3.13/test/mjsunit/regress/regress-2326.js Fri Oct 12 07:02:49
2012
@@ -0,0 +1,54 @@
+// 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.
+
+// This tests that we do not share optimized code across closures that
+// were optimized using OSR (for a particular OSR entry AST id) even if
+// caching of optimized code kicks in.
+
+function makeClosure() {
+ function f(mode, iterations) {
+ var accumulator = 0;
+ if (mode == 1) {
+ while (--iterations > 0) accumulator = Math.ceil(accumulator);
+ return 1;
+ } else {
+ while (--iterations > 0) accumulator = Math.floor(accumulator);
+ return 2;
+ }
+ }
+ return f;
+}
+
+// Generate two closures sharing the same underlying function literal.
+var f1 = makeClosure();
+var f2 = makeClosure();
+
+// This function should be optimized via OSR in the first tight loop.
+assertSame(1, f1(1, 100000));
+
+// This function should be optimized via OSR in the second tight loop.
+assertSame(2, f2(2, 100000));
=======================================
--- /dev/null
+++ /branches/3.13/test/mjsunit/regress/regress-crbug-150729.js Fri Oct 12
07:02:49 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.13/src/compiler.cc Thu Sep 6 06:50:42 2012
+++ /branches/3.13/src/compiler.cc Fri Oct 12 07:02:49 2012
@@ -746,8 +746,10 @@
static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
Handle<Code> code = info->code();
- Handle<JSFunction> function = info->closure();
- if (FLAG_cache_optimized_code && code->kind() ==
Code::OPTIMIZED_FUNCTION) {
+ if (FLAG_cache_optimized_code &&
+ info->osr_ast_id().IsNone() &&
+ code->kind() == Code::OPTIMIZED_FUNCTION) {
+ Handle<JSFunction> function = info->closure();
Handle<SharedFunctionInfo> shared(function->shared());
Handle<FixedArray> literals(function->literals());
Handle<Context> native_context(function->context()->native_context());
@@ -758,7 +760,9 @@
static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
- if (FLAG_cache_optimized_code && info->IsOptimizing()) {
+ if (FLAG_cache_optimized_code &&
+ info->osr_ast_id().IsNone() &&
+ info->IsOptimizing()) {
Handle<SharedFunctionInfo> shared = info->shared_info();
Handle<JSFunction> function = info->closure();
ASSERT(!function.is_null());
=======================================
--- /branches/3.13/src/ic-inl.h Tue Feb 21 02:08:21 2012
+++ /branches/3.13/src/ic-inl.h Fri Oct 12 07:02:49 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,11 @@
}
#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()->RecordCodeTargetPatch(address, target);
+ } else {
+ heap->incremental_marking()->RecordCodeTargetPatch(address, target);
+ }
PostPatching(address, target, old_target);
}
=======================================
--- /branches/3.13/src/mark-compact.cc Tue Aug 28 02:06:19 2012
+++ /branches/3.13/src/mark-compact.cc Fri Oct 12 07:02:49 2012
@@ -4078,6 +4078,20 @@
}
}
}
+
+
+void MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target)
{
+ ASSERT(heap()->gc_state() == Heap::MARK_COMPACT);
+ if (is_compacting()) {
+ Code* host = heap()->isolate()->inner_pointer_to_code_cache()->
+ GcSafeFindCodeForInnerPointer(pc);
+ MarkBit mark_bit = Marking::MarkBitFrom(host);
+ if (Marking::IsBlack(mark_bit)) {
+ RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host);
+ RecordRelocSlot(&rinfo, target);
+ }
+ }
+}
static inline SlotsBuffer::SlotType DecodeSlotType(
=======================================
--- /branches/3.13/src/mark-compact.h Thu Aug 16 08:44:54 2012
+++ /branches/3.13/src/mark-compact.h Fri Oct 12 07:02:49 2012
@@ -552,6 +552,7 @@
void RecordRelocSlot(RelocInfo* rinfo, Object* target);
void RecordCodeEntrySlot(Address slot, Code* target);
+ void RecordCodeTargetPatch(Address pc, Code* target);
INLINE(void RecordSlot(Object** anchor_slot, Object** slot, Object*
object));
=======================================
--- /branches/3.13/src/objects.cc Fri Sep 14 06:28:26 2012
+++ /branches/3.13/src/objects.cc Fri Oct 12 07:02:49 2012
@@ -651,11 +651,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();
@@ -10204,7 +10202,7 @@
MaybeObject* JSObject::GetPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
@@ -10222,7 +10220,7 @@
MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
- JSReceiver* receiver,
+ Object* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
@@ -10236,13 +10234,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.13/src/objects.h Fri Sep 14 06:28:26 2012
+++ /branches/3.13/src/objects.h Fri Oct 12 07:02:49 2012
@@ -1680,15 +1680,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.13/src/version.cc Wed Oct 10 14:29:48 2012
+++ /branches/3.13/src/version.cc Fri Oct 12 07:02:49 2012
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 13
#define BUILD_NUMBER 7
-#define PATCH_LEVEL 3
+#define PATCH_LEVEL 4
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.13/src/x64/lithium-codegen-x64.cc Tue Sep 11 06:22:37 2012
+++ /branches/3.13/src/x64/lithium-codegen-x64.cc Fri Oct 12 07:02:49 2012
@@ -3742,11 +3742,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.13/test/cctest/test-api.cc Fri Sep 14 06:28:26 2012
+++ /branches/3.13/test/cctest/test-api.cc Fri Oct 12 07:02:49 2012
@@ -17433,6 +17433,16 @@
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();");
+}
#ifndef WIN32
=======================================
--- /branches/3.13/test/cctest/test-heap.cc Wed Aug 29 08:32:24 2012
+++ /branches/3.13/test/cctest/test-heap.cc Fri Oct 12 07:02:49 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;
@@ -2238,3 +2240,62 @@
delete resource;
}
+
+
+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_object());
+ 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