Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Unified Diff: src/objects.cc

Issue 478043006: Rewrite StoreIC handling using the LookupIterator. Continued from patch 494153002 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 9d6be50535d46f9f01a7a531c8249b56fb28bf2e..6e67b5a812bd56382693322435a6b0940dc87ad9 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -108,6 +108,7 @@ MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
UNREACHABLE();
case LookupIterator::JSPROXY:
return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(),
@@ -150,9 +151,10 @@ Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object,
Handle<Object> JSObject::GetDataProperty(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
- case LookupIterator::NOT_FOUND:
case LookupIterator::ACCESS_CHECK:
case LookupIterator::INTERCEPTOR:
+ case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
UNREACHABLE();
case LookupIterator::JSPROXY:
it->NotFound();
@@ -2714,6 +2716,7 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> map) {
// static
Handle<Map> Map::Update(Handle<Map> map) {
+ if (!map->is_deprecated()) return map;
return GeneralizeRepresentation(map, 0, Representation::None(),
HeapType::None(map->GetIsolate()),
ALLOW_AS_CONSTANT);
@@ -2894,11 +2897,25 @@ MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
}
done = true;
break;
+
+ case LookupIterator::TRANSITION:
+ done = true;
+ break;
}
if (done) break;
}
+ // If the receiver is the JSGlobalObject, the store was contextual. In case
+ // the property did not exist yet on the global object itself, we have to
+ // throw a reference error in strict mode.
+ if (it->GetReceiver()->IsJSGlobalObject() && strict_mode == STRICT) {
+ Handle<Object> args[1] = {it->name()};
+ Handle<Object> error = it->isolate()->factory()->NewReferenceError(
+ "not_defined", HandleVector(args, 1));
+ return it->isolate()->Throw<Object>(error);
+ }
+
return AddDataProperty(it, value, NONE, strict_mode, store_mode);
}
@@ -2960,20 +2977,17 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
// TODO(verwaest): Throw a TypeError with a more specific message.
return WriteToReadOnlyProperty(it, value, strict_mode);
}
- Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
+
+ Handle<JSObject> receiver = it->GetStoreTarget();
// If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
// instead. If the prototype is Null, the proxy is detached.
- if (receiver->IsJSGlobalProxy()) {
- // Trying to assign to a detached proxy.
- PrototypeIterator iter(it->isolate(), receiver);
- if (iter.IsAtEnd()) return value;
- receiver =
- Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
- }
+ if (receiver->IsJSGlobalProxy()) return value;
- if (!it->name().is_identical_to(it->isolate()->factory()->hidden_string()) &&
- !receiver->map()->is_extensible()) {
+ // Possibly migrate to the most up-to-date map that will be able to store
+ // |value| under it->name() with |attributes|.
+ it->PrepareTransitionToDataProperty(value, attributes, store_mode);
+ if (it->state() != LookupIterator::TRANSITION) {
if (strict_mode == SLOPPY) return value;
Handle<Object> args[1] = {it->name()};
@@ -2981,10 +2995,7 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
"object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
return it->isolate()->Throw<Object>(error);
}
-
- // Possibly migrate to the most up-to-date map that will be able to store
- // |value| under it->name() with |attributes|.
- it->TransitionToDataProperty(value, attributes, store_mode);
+ it->ApplyTransitionToDataProperty();
// TODO(verwaest): Encapsulate dictionary handling better.
if (receiver->map()->is_dictionary_map()) {
@@ -3379,46 +3390,6 @@ Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
}
-void JSObject::LookupOwnRealNamedProperty(Handle<Name> name,
- LookupResult* result) {
- DisallowHeapAllocation no_gc;
- if (IsJSGlobalProxy()) {
- PrototypeIterator iter(GetIsolate(), this);
- if (iter.IsAtEnd()) return result->NotFound();
- DCHECK(iter.GetCurrent()->IsJSGlobalObject());
- return JSObject::cast(iter.GetCurrent())
- ->LookupOwnRealNamedProperty(name, result);
- }
-
- if (HasFastProperties()) {
- map()->LookupDescriptor(this, *name, result);
- // A property or a map transition was found. We return all of these result
- // types because LookupOwnRealNamedProperty is used when setting
- // properties where map transitions are handled.
- DCHECK(!result->IsFound() ||
- (result->holder() == this && result->IsFastPropertyType()));
- return;
- }
-
- int entry = property_dictionary()->FindEntry(name);
- if (entry != NameDictionary::kNotFound) {
- Object* value = property_dictionary()->ValueAt(entry);
- if (IsGlobalObject()) {
- PropertyDetails d = property_dictionary()->DetailsAt(entry);
- if (d.IsDeleted() || PropertyCell::cast(value)->value()->IsTheHole()) {
- result->NotFound();
- return;
- }
- value = PropertyCell::cast(value)->value();
- }
- result->DictionaryResult(this, entry);
- return;
- }
-
- result->NotFound();
-}
-
-
Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy,
Handle<Name> name) {
Isolate* isolate = proxy->GetIsolate();
@@ -3847,9 +3818,10 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
*name != it.isolate()->heap()->hidden_string();
for (; it.IsFound(); it.Next()) {
switch (it.state()) {
- case LookupIterator::NOT_FOUND:
- case LookupIterator::JSPROXY:
case LookupIterator::INTERCEPTOR:
+ case LookupIterator::JSPROXY:
+ case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
@@ -4022,6 +3994,7 @@ Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
UNREACHABLE();
case LookupIterator::JSPROXY:
return JSProxy::GetPropertyAttributesWithHandler(
@@ -4961,8 +4934,9 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
for (; it.IsFound(); it.Next()) {
switch (it.state()) {
- case LookupIterator::NOT_FOUND:
case LookupIterator::JSPROXY:
+ case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
if (it.HasAccess(v8::ACCESS_DELETE)) break;
@@ -5710,58 +5684,6 @@ int Map::NextFreePropertyIndex() {
}
-void JSReceiver::LookupOwn(Handle<Name> name, LookupResult* result) {
- DisallowHeapAllocation no_gc;
- DCHECK(name->IsName());
-
- if (IsJSGlobalProxy()) {
- PrototypeIterator iter(GetIsolate(), this);
- if (iter.IsAtEnd()) return result->NotFound();
- DCHECK(iter.GetCurrent()->IsJSGlobalObject());
- return JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result);
- }
-
- if (IsJSProxy()) {
- result->HandlerResult(JSProxy::cast(this));
- return;
- }
-
- // Do not use inline caching if the object is a non-global object
- // that requires access checks.
- if (IsAccessCheckNeeded()) {
- result->DisallowCaching();
- }
-
- JSObject* js_object = JSObject::cast(this);
-
- // Check for lookup interceptor except when bootstrapping.
- if (js_object->HasNamedInterceptor() &&
- !GetIsolate()->bootstrapper()->IsActive()) {
- result->InterceptorResult(js_object);
- return;
- }
-
- js_object->LookupOwnRealNamedProperty(name, result);
-}
-
-
-void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) {
- DisallowHeapAllocation no_gc;
- // Ecma-262 3rd 8.6.2.4
- for (PrototypeIterator iter(GetIsolate(), this,
- PrototypeIterator::START_AT_RECEIVER);
- !iter.IsAtEnd(); iter.Advance()) {
- JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result);
- if (result->IsFound()) return;
- if (name->IsOwn()) {
- result->NotFound();
- return;
- }
- }
- result->NotFound();
-}
-
-
static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
int len = array->length();
for (int i = 0; i < len; i++) {
@@ -6397,8 +6319,9 @@ MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object,
LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR);
for (; it.IsFound(); it.Next()) {
switch (it.state()) {
- case LookupIterator::NOT_FOUND:
case LookupIterator::INTERCEPTOR:
+ case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
UNREACHABLE();
case LookupIterator::ACCESS_CHECK:
@@ -6835,7 +6758,7 @@ Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
if (map->is_dictionary_map()) return map;
// Migrate to the newest map before storing the property.
- if (map->is_deprecated()) map = Update(map);
+ map = Update(map);
Handle<DescriptorArray> descriptors(map->instance_descriptors());
@@ -6857,8 +6780,8 @@ Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
// Dictionary maps can always have additional data properties.
if (map->is_dictionary_map()) return map;
- // Migrate to the newest map before transitioning to the new property.
- if (map->is_deprecated()) map = Update(map);
+ // Migrate to the newest map before storing the property.
+ map = Update(map);
int index = map->SearchTransition(*name);
if (index != TransitionArray::kNotFound) {
@@ -6868,9 +6791,7 @@ Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
// TODO(verwaest): Handle attributes better.
DescriptorArray* descriptors = transition->instance_descriptors();
if (descriptors->GetDetails(descriptor).attributes() != attributes) {
- return CopyGeneralizeAllRepresentations(transition, descriptor,
- FORCE_FIELD, attributes,
- "attributes mismatch");
+ return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
}
return Map::PrepareForDataProperty(transition, descriptor, value);
@@ -6925,7 +6846,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map,
}
// Migrate to the newest map before transitioning to the new property.
- if (map->is_deprecated()) map = Update(map);
+ map = Update(map);
PropertyNormalizationMode mode = map->is_prototype_map()
? KEEP_INOBJECT_PROPERTIES
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698