From: verwaest@chromium.org Date: Mon, 2 Sep 2013 16:32:11 +0000 (+0000) Subject: Allow uncacheable identifiers to go generic. X-Git-Tag: upstream/4.7.83~12707 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3f70c3b07b9b0de342bebe2270223eab1be6b0b4;p=platform%2Fupstream%2Fv8.git Allow uncacheable identifiers to go generic. BUG=v8:2867 R=jkummerow@chromium.org Review URL: https://chromiumcodereview.appspot.com/23453019 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16481 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ic.cc b/src/ic.cc index 2a1f83d..afce4f7 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1719,7 +1719,8 @@ MaybeObject* StoreIC::Store(State state, // Strict mode doesn't allow setting non-existent global property. return ReferenceError("not_defined", name); } else if (FLAG_use_ic && - (lookup.IsNormal() || + (!name->IsCacheable(isolate()) || + lookup.IsNormal() || (lookup.IsField() && lookup.CanHoldValue(value)))) { Handle stub = strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); diff --git a/src/objects.cc b/src/objects.cc index 2183fb4..5b4a657 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -1909,25 +1909,6 @@ MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, } -static bool IsIdentifier(UnicodeCache* cache, Name* name) { - // Checks whether the buffer contains an identifier (no escape). - if (!name->IsString()) return false; - String* string = String::cast(name); - if (string->length() == 0) return false; - ConsStringIteratorOp op; - StringCharacterStream stream(string, &op); - if (!cache->IsIdentifierStart(stream.GetNext())) { - return false; - } - while (stream.HasMore()) { - if (!cache->IsIdentifierPart(stream.GetNext())) { - return false; - } - } - return true; -} - - MaybeObject* JSObject::AddFastProperty(Name* name, Object* value, PropertyAttributes attributes, @@ -1943,10 +1924,7 @@ MaybeObject* JSObject::AddFastProperty(Name* name, // hidden strings) and is not a real identifier. // Normalize the object if it will have too many fast properties. Isolate* isolate = GetHeap()->isolate(); - if ((!name->IsSymbol() && - !IsIdentifier(isolate->unicode_cache(), name) && - name != isolate->heap()->hidden_string()) || - TooManyFastProperties(store_mode)) { + if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) { MaybeObject* maybe_failure = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); if (maybe_failure->IsFailure()) return maybe_failure; @@ -7955,6 +7933,32 @@ bool DescriptorArray::IsEqualTo(DescriptorArray* other) { #endif +static bool IsIdentifier(UnicodeCache* cache, Name* name) { + // Checks whether the buffer contains an identifier (no escape). + if (!name->IsString()) return false; + String* string = String::cast(name); + if (string->length() == 0) return false; + ConsStringIteratorOp op; + StringCharacterStream stream(string, &op); + if (!cache->IsIdentifierStart(stream.GetNext())) { + return false; + } + while (stream.HasMore()) { + if (!cache->IsIdentifierPart(stream.GetNext())) { + return false; + } + } + return true; +} + + +bool Name::IsCacheable(Isolate* isolate) { + return IsSymbol() || + IsIdentifier(isolate->unicode_cache(), this) || + this == isolate->heap()->hidden_string(); +} + + bool String::LooksValid() { if (!Isolate::Current()->heap()->Contains(this)) return false; return true; diff --git a/src/objects.h b/src/objects.h index 18acba9..e4017ef 100644 --- a/src/objects.h +++ b/src/objects.h @@ -7994,6 +7994,8 @@ class Name: public HeapObject { // Casting. static inline Name* cast(Object* obj); + bool IsCacheable(Isolate* isolate); + DECLARE_PRINTER(Name) // Layout description. diff --git a/test/mjsunit/regress/regress-store-uncacheable.js b/test/mjsunit/regress/regress-store-uncacheable.js new file mode 100644 index 0000000..e9c9fc2 --- /dev/null +++ b/test/mjsunit/regress/regress-store-uncacheable.js @@ -0,0 +1,40 @@ +// 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: --allow-natives-syntax + +function f() { + var o = {}; + o[""] = 123; +} + +f(); +f(); +f(); +%OptimizeFunctionOnNextCall(f); +f(); +assertOptimized(f);