Revision: 12098
Author: [email protected]
Date: Mon Jul 16 07:47:28 2012
Log: Removing LookupTransition from LookupRealNamedProperty and
related utility functions.
Callsites now have to manually lookup transitions if required. This
avoids unnecessary overhead of looking up transitions when we don't need
them. This also allows us to use IsFound() in many places where
IsProperty() was required previously.
Review URL: https://chromiumcodereview.appspot.com/10779012
http://code.google.com/p/v8/source/detail?r=12098
Modified:
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/profile-generator.cc
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/stub-cache.cc
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Mon Jul 16 07:02:50 2012
+++ /branches/bleeding_edge/src/bootstrapper.cc Mon Jul 16 07:47:28 2012
@@ -2175,7 +2175,7 @@
LookupResult result(isolate());
to->LocalLookup(descs->GetKey(i), &result);
// If the property is already there we skip it
- if (result.IsProperty()) continue;
+ if (result.IsFound()) continue;
HandleScope inner;
ASSERT(!to->HasFastProperties());
// Add to dictionary.
@@ -2208,7 +2208,7 @@
// If the property is already there we skip it.
LookupResult result(isolate());
to->LocalLookup(String::cast(raw_key), &result);
- if (result.IsProperty()) continue;
+ if (result.IsFound()) continue;
// Set the property.
Handle<String> key = Handle<String>(String::cast(raw_key));
Handle<Object> value = Handle<Object>(properties->ValueAt(i));
=======================================
--- /branches/bleeding_edge/src/ic.cc Mon Jul 16 07:02:50 2012
+++ /branches/bleeding_edge/src/ic.cc Mon Jul 16 07:47:28 2012
@@ -445,14 +445,14 @@
}
holder->LocalLookupRealNamedProperty(*name, lookup);
- if (lookup->IsProperty()) {
+ if (lookup->IsFound()) {
ASSERT(!lookup->IsInterceptor());
return;
}
Handle<Object> proto(holder->GetPrototype());
if (proto->IsNull()) {
- lookup->NotFound();
+ ASSERT(!lookup->IsFound());
return;
}
@@ -533,7 +533,7 @@
LookupResult lookup(isolate());
LookupForRead(object, name, &lookup);
- if (!lookup.IsProperty()) {
+ if (!lookup.IsFound()) {
// If the object does not have the requested property, check which
// exception we need to throw.
return IsContextual(object)
@@ -900,7 +900,7 @@
LookupForRead(object, name, &lookup);
// If we did not find a property, check if we need to throw an exception.
- if (!lookup.IsProperty()) {
+ if (!lookup.IsFound()) {
if (IsContextual(object)) {
return ReferenceError("not_defined", name);
}
@@ -1166,7 +1166,7 @@
LookupForRead(object, name, &lookup);
// If we did not find a property, check if we need to throw an
exception.
- if (!lookup.IsProperty() && IsContextual(object)) {
+ if (!lookup.IsFound() && IsContextual(object)) {
return ReferenceError("not_defined", name);
}
@@ -1317,6 +1317,9 @@
Handle<String> name,
LookupResult* lookup) {
receiver->LocalLookup(*name, lookup);
+ if (!lookup->IsFound()) {
+ receiver->map()->LookupTransition(*receiver, *name, lookup);
+ }
if (!StoreICableLookup(lookup)) {
// 2nd chance: There can be accessors somewhere in the prototype
chain. Note
// that we explicitly exclude native accessors for now, because the
stubs
=======================================
--- /branches/bleeding_edge/src/objects.cc Mon Jul 16 07:02:50 2012
+++ /branches/bleeding_edge/src/objects.cc Mon Jul 16 07:47:28 2012
@@ -406,13 +406,11 @@
} else {
result->holder()->LocalLookupRealNamedProperty(name, &r);
}
- if (r.IsProperty()) {
- return GetPropertyAttributeWithFailedAccessCheck(receiver,
- &r,
- name,
-
continue_search);
- }
- break;
+ if (!r.IsFound()) break;
+ return GetPropertyAttributeWithFailedAccessCheck(receiver,
+ &r,
+ name,
+ continue_search);
}
case HANDLER:
@@ -1747,9 +1745,10 @@
// Check local property, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
+ if (!result.IsFound()) map()->LookupTransition(this, name, &result);
if (result.IsFound()) {
- // An existing property, a map transition or a null descriptor was
- // found. Use set property to handle all these cases.
+ // An existing property or a map transition was found. Use set
property to
+ // handle all these cases.
return SetProperty(&result, name, value, attributes, strict_mode);
}
bool done = false;
@@ -1914,6 +1913,9 @@
JSReceiver::StoreFromKeyed
store_mode) {
LookupResult result(GetIsolate());
LocalLookup(name, &result);
+ if (!result.IsFound()) {
+ map()->LookupTransition(JSObject::cast(this), name, &result);
+ }
return SetProperty(&result, name, value, attributes, strict_mode,
store_mode);
}
@@ -2354,7 +2356,7 @@
}
if (HasFastProperties()) {
- map()->LookupTransitionOrDescriptor(this, name, result);
+ map()->LookupDescriptor(this, name, result);
// A property or a map transition was found. We return all of these
result
// types because LocalLookupRealNamedProperty is used when setting
// properties where map transitions are handled.
@@ -2394,7 +2396,7 @@
void JSObject::LookupRealNamedProperty(String* name, LookupResult* result)
{
LocalLookupRealNamedProperty(name, result);
- if (result->IsProperty()) return;
+ if (result->IsFound()) return;
LookupRealNamedPropertyInPrototypes(name, result);
}
@@ -2410,8 +2412,8 @@
return result->HandlerResult(JSProxy::cast(pt));
}
JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
- ASSERT(!(result->IsProperty() && result->type() == INTERCEPTOR));
- if (result->IsProperty()) return;
+ ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR));
+ if (result->IsFound()) return;
}
result->NotFound();
}
@@ -2933,6 +2935,7 @@
Isolate* isolate = GetIsolate();
LookupResult result(isolate);
LocalLookup(name, &result);
+ if (!result.IsFound()) map()->LookupTransition(this, name, &result);
// Check access rights if needed.
if (IsAccessCheckNeeded()) {
if (!isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
@@ -3021,7 +3024,7 @@
// Check local property, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
- if (result.IsProperty()) return result.GetAttributes();
+ if (result.IsFound()) return result.GetAttributes();
if (continue_search) {
// Continue searching via the prototype chain.
@@ -3114,7 +3117,7 @@
receiver, result, name, continue_search);
}
}
- if (result->IsProperty()) {
+ if (result->IsFound()) {
switch (result->type()) {
case NORMAL: // fall through
case FIELD:
@@ -3700,7 +3703,7 @@
// Check local property, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
- if (!result.IsProperty()) return GetHeap()->true_value();
+ if (!result.IsFound()) return GetHeap()->true_value();
// Normalize object if needed.
Object* obj;
@@ -3849,7 +3852,7 @@
} else {
LookupResult result(isolate);
LocalLookup(name, &result);
- if (!result.IsProperty()) return isolate->heap()->true_value();
+ if (!result.IsFound()) return isolate->heap()->true_value();
// Ignore attributes if forcing a deletion.
if (result.IsDontDelete() && mode != FORCE_DELETION) {
if (mode == STRICT_DELETION) {
@@ -4199,21 +4202,22 @@
}
-void JSReceiver::Lookup(String* name, LookupResult* result) {
+void JSReceiver::Lookup(String* name,
+ LookupResult* result) {
// Ecma-262 3rd 8.6.2.4
Heap* heap = GetHeap();
for (Object* current = this;
current != heap->null_value();
current = JSObject::cast(current)->GetPrototype()) {
JSReceiver::cast(current)->LocalLookup(name, result);
- if (result->IsProperty()) return;
+ if (result->IsFound()) return;
}
result->NotFound();
}
// Search object and its prototype chain for callback properties.
-void JSObject::LookupCallback(String* name, LookupResult* result) {
+void JSObject::LookupCallbackProperty(String* name, LookupResult* result) {
Heap* heap = GetHeap();
for (Object* current = this;
current != heap->null_value() && current->IsJSObject();
@@ -4384,8 +4388,8 @@
// to be overwritten because allowing overwriting could potentially
// cause security problems.
LookupResult callback_result(GetIsolate());
- LookupCallback(name, &callback_result);
- if (callback_result.IsProperty()) {
+ LookupCallbackProperty(name, &callback_result);
+ if (callback_result.IsFound()) {
Object* obj = callback_result.GetCallbackObject();
if (obj->IsAccessorInfo() &&
AccessorInfo::cast(obj)->prohibits_overwriting()) {
@@ -4693,23 +4697,22 @@
break;
}
- { MaybeObject* maybe_ok =
- SetElementCallback(index, info, info->property_attributes());
- if (maybe_ok->IsFailure()) return maybe_ok;
- }
+ MaybeObject* maybe_ok =
+ SetElementCallback(index, info, info->property_attributes());
+ if (maybe_ok->IsFailure()) return maybe_ok;
} else {
// Lookup the name.
LookupResult result(isolate);
LocalLookup(name, &result);
// ES5 forbids turning a property into an accessor if it's not
// configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table
5).
- if (result.IsProperty() && (result.IsReadOnly() ||
result.IsDontDelete())) {
+ if (result.IsFound() && (result.IsReadOnly() ||
result.IsDontDelete())) {
return isolate->heap()->undefined_value();
}
- { MaybeObject* maybe_ok =
- SetPropertyCallback(name, info, info->property_attributes());
- if (maybe_ok->IsFailure()) return maybe_ok;
- }
+
+ MaybeObject* maybe_ok =
+ SetPropertyCallback(name, info, info->property_attributes());
+ if (maybe_ok->IsFailure()) return maybe_ok;
}
return this;
@@ -4755,7 +4758,7 @@
obj = JSReceiver::cast(obj)->GetPrototype()) {
LookupResult result(heap->isolate());
JSReceiver::cast(obj)->LocalLookup(name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
if (result.IsReadOnly()) return heap->undefined_value();
if (result.IsPropertyCallbacks()) {
Object* obj = result.GetCallbackObject();
@@ -7641,7 +7644,7 @@
LookupResult result(heap->isolate());
String* name = GetThisPropertyAssignmentName(i);
receiver->LocalLookup(name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
switch (result.type()) {
case NORMAL:
case FIELD:
@@ -10174,7 +10177,7 @@
// Check local property in holder, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
return GetProperty(receiver, &result, name, attributes);
}
// Continue searching via the prototype chain.
@@ -10192,7 +10195,7 @@
// Check local property in holder, ignore interceptor.
LookupResult result(GetIsolate());
LocalLookupRealNamedProperty(name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
return GetProperty(receiver, &result, name, attributes);
}
return GetHeap()->undefined_value();
@@ -10251,7 +10254,7 @@
LookupResult result(isolate);
LocalLookupRealNamedProperty(key, &result);
- return result.IsProperty() && !result.IsInterceptor();
+ return result.IsFound() && !result.IsInterceptor();
}
=======================================
--- /branches/bleeding_edge/src/objects.h Mon Jul 16 07:02:50 2012
+++ /branches/bleeding_edge/src/objects.h Mon Jul 16 07:47:28 2012
@@ -1876,7 +1876,7 @@
void LookupRealNamedPropertyInPrototypes(String* name, LookupResult*
result);
MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes(
uint32_t index, Object* value, bool* found, StrictModeFlag
strict_mode);
- void LookupCallback(String* name, LookupResult* result);
+ void LookupCallbackProperty(String* name, LookupResult* result);
// Returns the number of properties on this object filtering out
properties
// with the specified attributes (ignoring interceptors).
=======================================
--- /branches/bleeding_edge/src/profile-generator.cc Tue Jul 10 06:31:36
2012
+++ /branches/bleeding_edge/src/profile-generator.cc Mon Jul 16 07:47:28
2012
@@ -2300,11 +2300,12 @@
Object* constructor_prop = NULL;
LookupResult result(heap->isolate());
object->LocalLookupRealNamedProperty(heap->constructor_symbol(),
&result);
- if (result.IsProperty()) {
- constructor_prop = result.GetLazyValue();
- }
+ if (!result.IsFound()) return object->constructor_name();
+
+ constructor_prop = result.GetLazyValue();
if (constructor_prop->IsJSFunction()) {
- Object* maybe_name =
JSFunction::cast(constructor_prop)->shared()->name();
+ Object* maybe_name =
+ JSFunction::cast(constructor_prop)->shared()->name();
if (maybe_name->IsString()) {
String* name = String::cast(maybe_name);
if (name->length() > 0) return name;
=======================================
--- /branches/bleeding_edge/src/runtime.cc Mon Jul 16 07:02:50 2012
+++ /branches/bleeding_edge/src/runtime.cc Mon Jul 16 07:47:28 2012
@@ -953,13 +953,13 @@
LookupResult* result) {
obj->LocalLookupRealNamedProperty(name, result);
- if (!result->IsProperty()) {
- Object* proto = obj->GetPrototype();
- if (proto->IsJSObject() &&
- JSObject::cast(proto)->map()->is_hidden_prototype())
- GetOwnPropertyImplementation(JSObject::cast(proto),
- name, result);
- }
+ if (result->IsFound()) return;
+
+ Object* proto = obj->GetPrototype();
+ if (proto->IsJSObject() &&
+ JSObject::cast(proto)->map()->is_hidden_prototype())
+ GetOwnPropertyImplementation(JSObject::cast(proto),
+ name, result);
}
@@ -1373,14 +1373,14 @@
Object* obj = *global;
do {
JSObject::cast(obj)->LocalLookup(*name, &lookup);
- if (lookup.IsProperty()) break;
+ if (lookup.IsFound()) break;
obj = obj->GetPrototype();
} while (obj->IsJSObject() &&
JSObject::cast(obj)->map()->is_hidden_prototype());
} else {
global->Lookup(*name, &lookup);
}
- if (lookup.IsProperty()) {
+ if (lookup.IsFound()) {
// We found an existing property. Unless it was an interceptor
// that claims the property is absent, skip this declaration.
if (!lookup.IsInterceptor()) continue;
@@ -1416,10 +1416,10 @@
LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
- if (!lookup.IsProperty() || is_function || is_module) {
+ if (!lookup.IsFound() || is_function || is_module) {
// If the local property exists, check that we can reconfigure it
// as required for function declarations.
- if (lookup.IsProperty() && lookup.IsDontDelete()) {
+ if (lookup.IsFound() && lookup.IsDontDelete()) {
if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
lookup.IsPropertyCallbacks()) {
return ThrowRedeclarationError(
@@ -1634,7 +1634,7 @@
// We use SetLocalPropertyIgnoreAttributes instead
LookupResult lookup(isolate);
global->LocalLookup(*name, &lookup);
- if (!lookup.IsProperty()) {
+ if (!lookup.IsFound()) {
return global->SetLocalPropertyIgnoreAttributes(*name,
*value,
attributes);
@@ -4558,7 +4558,7 @@
// map. The current version of SetObjectProperty does not handle
attributes
// correctly in the case where a property is a field and is reset with
// new attributes.
- if (result.IsProperty() &&
+ if (result.IsFound() &&
(attr != result.GetAttributes() || result.IsPropertyCallbacks())) {
// New attributes - normalize to avoid writing to instance descriptor
if (js_object->IsJSGlobalProxy()) {
@@ -10421,7 +10421,7 @@
for (int i = 0; i < length; i++) {
LookupResult result(isolate);
jsproto->LocalLookup(*name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
// LookupResult is not GC safe as it holds raw object pointers.
// GC can happen later in this code so put the required fields into
// local variables using handles when required for later use.
@@ -10478,7 +10478,7 @@
LookupResult result(isolate);
obj->Lookup(*name, &result);
- if (result.IsProperty()) {
+ if (result.IsFound()) {
return DebugLookupResultValue(isolate->heap(), *obj, *name, &result,
NULL);
}
return isolate->heap()->undefined_value();
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Wed Jul 4 04:40:51 2012
+++ /branches/bleeding_edge/src/stub-cache.cc Mon Jul 16 07:47:28 2012
@@ -1361,11 +1361,8 @@
Handle<String> name,
LookupResult* lookup) {
holder->LocalLookupRealNamedProperty(*name, lookup);
- if (lookup->IsProperty()) return;
-
- lookup->NotFound();
+ if (lookup->IsFound()) return;
if (holder->GetPrototype()->IsNull()) return;
-
holder->GetPrototype()->Lookup(*name, lookup);
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev