Commit 657422c2 authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Use the syntax of a property addition as a hint for controlling the fast-mode...

Use the syntax of a property addition as a hint for controlling the fast-mode vs. dictionary mode heursitics on objects.
Review URL: https://chromiumcodereview.appspot.com/10537050

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11732 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5e8cc58b
......@@ -1408,7 +1408,11 @@ MaybeObject* StoreIC::Store(State state,
}
// Set the property.
return receiver->SetProperty(*name, *value, NONE, strict_mode);
return receiver->SetProperty(*name,
*value,
NONE,
strict_mode,
JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
}
......
......@@ -1611,7 +1611,8 @@ bool JSObject::HasFastProperties() {
}
bool JSObject::TooManyFastProperties(int properties) {
bool JSObject::TooManyFastProperties(int properties,
JSObject::StoreFromKeyed store_mode) {
// Allow extra fast properties if the object has more than
// kFastPropertiesSoftLimit in-object properties. When this is the case,
// it is very unlikely that the object is being used as a dictionary
......@@ -1620,7 +1621,8 @@ bool JSObject::TooManyFastProperties(int properties) {
int inobject = map()->inobject_properties();
int limit;
if (map()->used_for_prototype()) {
if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ||
map()->used_for_prototype()) {
limit = Max(inobject, kMaxFastProperties);
} else {
limit = Max(inobject, kFastPropertiesSoftLimit);
......
......@@ -1514,7 +1514,8 @@ static bool IsIdentifier(UnicodeCache* cache,
MaybeObject* JSObject::AddFastProperty(String* name,
Object* value,
PropertyAttributes attributes) {
PropertyAttributes attributes,
StoreFromKeyed store_mode) {
ASSERT(!IsJSGlobalProxy());
// Normalize the object if the name is an actual string (not the
......@@ -1580,7 +1581,7 @@ MaybeObject* JSObject::AddFastProperty(String* name,
}
if (map()->unused_property_fields() == 0) {
if (TooManyFastProperties(properties()->length())) {
if (TooManyFastProperties(properties()->length(), store_mode)) {
Object* obj;
{ MaybeObject* maybe_obj =
NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
......@@ -1710,7 +1711,8 @@ MaybeObject* JSObject::AddSlowProperty(String* name,
MaybeObject* JSObject::AddProperty(String* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode) {
StrictModeFlag strict_mode,
JSReceiver::StoreFromKeyed store_mode) {
ASSERT(!IsJSGlobalProxy());
Map* map_of_this = map();
Heap* heap = GetHeap();
......@@ -1733,7 +1735,7 @@ MaybeObject* JSObject::AddProperty(String* name,
JSFunction::cast(value),
attributes);
} else {
return AddFastProperty(name, value, attributes);
return AddFastProperty(name, value, attributes, store_mode);
}
} else {
// Normalize the object to prevent very large instance descriptors.
......@@ -1830,7 +1832,7 @@ MaybeObject* JSObject::ConvertDescriptorToField(String* name,
Object* new_value,
PropertyAttributes attributes) {
if (map()->unused_property_fields() == 0 &&
TooManyFastProperties(properties()->length())) {
TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) {
Object* obj;
{ MaybeObject* maybe_obj =
NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
......@@ -1945,10 +1947,11 @@ Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
MaybeObject* JSReceiver::SetProperty(String* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode) {
StrictModeFlag strict_mode,
JSReceiver::StoreFromKeyed store_mode) {
LookupResult result(GetIsolate());
LocalLookup(name, &result);
return SetProperty(&result, name, value, attributes, strict_mode);
return SetProperty(&result, name, value, attributes, strict_mode, store_mode);
}
......@@ -2619,13 +2622,14 @@ MaybeObject* JSReceiver::SetProperty(LookupResult* result,
String* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode) {
StrictModeFlag strict_mode,
JSReceiver::StoreFromKeyed store_mode) {
if (result->IsFound() && result->type() == HANDLER) {
return result->proxy()->SetPropertyWithHandler(
this, key, value, attributes, strict_mode);
} else {
return JSObject::cast(this)->SetPropertyForResult(
result, key, value, attributes, strict_mode);
result, key, value, attributes, strict_mode, store_mode);
}
}
......@@ -2908,7 +2912,8 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
String* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode) {
StrictModeFlag strict_mode,
StoreFromKeyed store_mode) {
Heap* heap = GetHeap();
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
......@@ -2939,7 +2944,7 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
if (proto->IsNull()) return value;
ASSERT(proto->IsJSGlobalObject());
return JSObject::cast(proto)->SetPropertyForResult(
result, name, value, attributes, strict_mode);
result, name, value, attributes, strict_mode, store_mode);
}
if (!result->IsProperty() && !IsJSContextExtensionObject()) {
......@@ -2951,7 +2956,7 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
if (!result->IsFound()) {
// Neither properties nor transitions found.
return AddProperty(name, value, attributes, strict_mode);
return AddProperty(name, value, attributes, strict_mode, store_mode);
}
if (result->IsReadOnly() && result->IsProperty()) {
if (strict_mode == kStrictMode) {
......
......@@ -1353,6 +1353,13 @@ class JSReceiver: public HeapObject {
FORCE_DELETION
};
// A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
// a keyed store is of the form a[expression] = foo.
enum StoreFromKeyed {
MAY_BE_STORE_FROM_KEYED,
CERTAINLY_NOT_STORE_FROM_KEYED
};
// Casting.
static inline JSReceiver* cast(Object* obj);
......@@ -1362,15 +1369,19 @@ class JSReceiver: public HeapObject {
PropertyAttributes attributes,
StrictModeFlag strict_mode);
// Can cause GC.
MUST_USE_RESULT MaybeObject* SetProperty(String* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
String* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetProperty(
String* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
MUST_USE_RESULT MaybeObject* SetProperty(
LookupResult* result,
String* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSReceiver* setter,
Object* value);
......@@ -1524,7 +1535,8 @@ class JSObject: public JSReceiver {
String* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
StrictModeFlag strict_mode,
StoreFromKeyed store_mode);
MUST_USE_RESULT MaybeObject* SetPropertyWithFailedAccessCheck(
LookupResult* result,
String* name,
......@@ -1921,9 +1933,11 @@ class JSObject: public JSReceiver {
PropertyAttributes attributes);
// Add a property to a fast-case object.
MUST_USE_RESULT MaybeObject* AddFastProperty(String* name,
Object* value,
PropertyAttributes attributes);
MUST_USE_RESULT MaybeObject* AddFastProperty(
String* name,
Object* value,
PropertyAttributes attributes,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
// Add a property to a slow-case object.
MUST_USE_RESULT MaybeObject* AddSlowProperty(String* name,
......@@ -1931,10 +1945,12 @@ class JSObject: public JSReceiver {
PropertyAttributes attributes);
// Add a property to an object.
MUST_USE_RESULT MaybeObject* AddProperty(String* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* AddProperty(
String* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
// Convert the object to use the canonical dictionary
// representation. If the object is expected to have additional properties
......@@ -2054,7 +2070,7 @@ class JSObject: public JSReceiver {
// Maximal number of fast properties for the JSObject. Used to
// restrict the number of map transitions to avoid an explosion in
// the number of maps for objects used as dictionaries.
inline bool TooManyFastProperties(int properties);
inline bool TooManyFastProperties(int properties, StoreFromKeyed store_mode);
// Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
// Also maximal value of JSArray's length property.
......@@ -2077,7 +2093,7 @@ class JSObject: public JSReceiver {
static const int kInitialMaxFastElementArray = 100000;
static const int kFastPropertiesSoftLimit = 12;
static const int kMaxFastProperties = 32;
static const int kMaxFastProperties = 64;
static const int kMaxInstanceSize = 255 * kPointerSize;
// When extending the backing storage for property values, we increase
// its size by more than the 1 entry necessary, so sequentially adding fields
......
// 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
// Check that keyed stores make things go dict mode faster than non-keyed
// stores.
function AddProps(obj) {
for (var i = 0; i < 26; i++) {
obj["x" + i] = 0;
}
}
function AddPropsNonKeyed(obj) {
obj.x0 = 0;
obj.x1 = 0;
obj.x2 = 0;
obj.x3 = 0;
obj.x4 = 0;
obj.x5 = 0;
obj.x6 = 0;
obj.x7 = 0;
obj.x8 = 0;
obj.x9 = 0;
obj.x10 = 0;
obj.x11 = 0;
obj.x12 = 0;
obj.x13 = 0;
obj.x14 = 0;
obj.x15 = 0;
obj.x16 = 0;
obj.x17 = 0;
obj.x18 = 0;
obj.x19 = 0;
obj.x20 = 0;
obj.x21 = 0;
obj.x22 = 0;
obj.x23 = 0;
obj.x24 = 0;
obj.x25 = 0;
}
var keyed = {};
AddProps(keyed);
assertFalse(%HasFastProperties(keyed));
var non_keyed = {};
AddPropsNonKeyed(non_keyed);
assertTrue(%HasFastProperties(non_keyed));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment