From eee5884f8d33731ebc512d324cee1621b06a206e Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Thu, 4 Apr 2013 08:29:25 +0000 Subject: [PATCH] Add extra flag for load-ic stubs in code cache. This allows to distinguish between stubs compiled for the current object from stubs compiled for objects that have the current object as a prototype. BUG=v8:2593 R=verwaest@chromium.org Review URL: https://chromiumcodereview.appspot.com/13552003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14132 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.h | 11 +++++++ src/stub-cache.cc | 28 ++++++++++------- src/stub-cache.h | 4 +-- test/mjsunit/regress/regress-2593.js | 61 ++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 test/mjsunit/regress/regress-2593.js diff --git a/src/objects.h b/src/objects.h index a796b7e..37be25f 100644 --- a/src/objects.h +++ b/src/objects.h @@ -4354,6 +4354,11 @@ class Code: public HeapObject { NONEXISTENT }; + enum StubHolder { + OWN_STUB, + PROTOTYPE_STUB + }; + enum { NUMBER_OF_KINDS = LAST_IC_KIND + 1 }; @@ -4549,6 +4554,8 @@ class Code: public HeapObject { class ExtraICStateKeyedAccessStoreMode: public BitField {}; // NOLINT + class ExtraICStateStubHolder: public BitField {}; + static inline StrictModeFlag GetStrictMode(ExtraICState extra_ic_state) { return ExtraICStateStrictMode::decode(extra_ic_state); } @@ -4565,6 +4572,10 @@ class Code: public HeapObject { ExtraICStateStrictMode::encode(strict_mode); } + static inline ExtraICState ComputeExtraICState(StubHolder stub_holder) { + return ExtraICStateStubHolder::encode(stub_holder); + } + // Flags operations. static inline Flags ComputeFlags( Kind kind, diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 8185325..553c6f5 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -123,10 +123,13 @@ Handle StubCache::FindIC(Handle name, Handle StubCache::FindHandler(Handle name, + Handle receiver, Handle stub_holder, Code::Kind kind, - Code::StubType type, - Code::ExtraICState extra_ic_state) { + Code::StubType type) { + Code::ExtraICState extra_ic_state = Code::ComputeExtraICState( + receiver.is_identical_to(stub_holder) ? Code::OWN_STUB + : Code::PROTOTYPE_STUB); ASSERT(type != Code::NORMAL); Code::Flags flags = Code::ComputeMonomorphicFlags( Code::STUB, extra_ic_state, type, kind); @@ -194,7 +197,7 @@ Handle StubCache::ComputeLoadNonexistent(Handle name, // Compile the stub that is either shared for all names or // name specific if there are global objects involved. Handle handler = FindHandler( - cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT); + cache_name, receiver, receiver, Code::LOAD_IC, Code::NONEXISTENT); if (!handler.is_null()) return handler; LoadStubCompiler compiler(isolate_); @@ -218,7 +221,7 @@ Handle StubCache::ComputeLoadField(Handle name, Handle stub_holder = StubHolder(receiver, holder); Handle stub = FindHandler( - name, stub_holder, Code::LOAD_IC, Code::FIELD); + name, receiver, stub_holder, Code::LOAD_IC, Code::FIELD); if (!stub.is_null()) return stub; LoadStubCompiler compiler(isolate_); @@ -237,7 +240,7 @@ Handle StubCache::ComputeLoadCallback( ASSERT(v8::ToCData
(callback->getter()) != 0); Handle stub_holder = StubHolder(receiver, holder); Handle stub = FindHandler( - name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); + name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS); if (!stub.is_null()) return stub; LoadStubCompiler compiler(isolate_); @@ -254,7 +257,7 @@ Handle StubCache::ComputeLoadViaGetter(Handle name, Handle getter) { Handle stub_holder = StubHolder(receiver, holder); Handle stub = FindHandler( - name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); + name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS); if (!stub.is_null()) return stub; LoadStubCompiler compiler(isolate_); @@ -271,7 +274,7 @@ Handle StubCache::ComputeLoadConstant(Handle name, Handle value) { Handle stub_holder = StubHolder(receiver, holder); Handle handler = FindHandler( - name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); + name, receiver, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); if (!handler.is_null()) return handler; LoadStubCompiler compiler(isolate_); @@ -287,7 +290,7 @@ Handle StubCache::ComputeLoadInterceptor(Handle name, Handle holder) { Handle stub_holder = StubHolder(receiver, holder); Handle stub = FindHandler( - name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); + name, receiver, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); if (!stub.is_null()) return stub; LoadStubCompiler compiler(isolate_); @@ -334,7 +337,7 @@ Handle StubCache::ComputeKeyedLoadField(Handle name, Handle stub_holder = StubHolder(receiver, holder); Handle stub = FindHandler( - name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); + name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); if (!stub.is_null()) return stub; KeyedLoadStubCompiler compiler(isolate_); @@ -351,7 +354,8 @@ Handle StubCache::ComputeKeyedLoadConstant(Handle name, Handle value) { Handle stub_holder = StubHolder(receiver, holder); Handle handler = FindHandler( - name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION); + name, receiver, stub_holder, Code::KEYED_LOAD_IC, + Code::CONSTANT_FUNCTION); if (!handler.is_null()) return handler; KeyedLoadStubCompiler compiler(isolate_); @@ -366,7 +370,7 @@ Handle StubCache::ComputeKeyedLoadInterceptor(Handle name, Handle holder) { Handle stub_holder = StubHolder(receiver, holder); Handle stub = FindHandler( - name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); + name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); if (!stub.is_null()) return stub; KeyedLoadStubCompiler compiler(isolate_); @@ -384,7 +388,7 @@ Handle StubCache::ComputeKeyedLoadCallback( Handle callback) { Handle stub_holder = StubHolder(receiver, holder); Handle stub = FindHandler( - name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); + name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); if (!stub.is_null()) return stub; KeyedLoadStubCompiler compiler(isolate_); diff --git a/src/stub-cache.h b/src/stub-cache.h index 673cb1b..bca3b7b 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -85,10 +85,10 @@ class StubCache { Handle FindHandler( Handle name, + Handle receiver, Handle stub_holder, Code::Kind kind, - Code::StubType type, - Code::ExtraICState extra_state = Code::kNoExtraICState); + Code::StubType type); Handle ComputeMonomorphicIC(Handle receiver, Handle handler, diff --git a/test/mjsunit/regress/regress-2593.js b/test/mjsunit/regress/regress-2593.js new file mode 100644 index 0000000..b51b41c --- /dev/null +++ b/test/mjsunit/regress/regress-2593.js @@ -0,0 +1,61 @@ +// Copyright 2013 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_gc + +p1 = { }; +p2 = { }; +p3 = { x : 1 }; +p2.__proto__ = p3 +p1.__proto__ = p2 + +// Normalize p1. +p1.z = 1 +delete p1.z + +// Make sure all objects are in old space. +for (var i = 0; i < 10; i++) gc(); + +function f2() { + p2.x; +} + +function f1() { + return p1.x; +} + +// Create load stub in p2. +for (var i = 0; i < 10; i++) f2(); + +// Create load stub in p2 for p1. +for (var i = 0; i < 10; i++) f1(); + +assertEquals(1, f1()); + +p2.x = 2; + +assertEquals(2, f1()); -- 2.7.4