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

Unified Diff: src/ic.cc

Issue 223193005: Get rid of the TRANSITION PropertyType and consistently use CanHoldValue(). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use number_ for LastAdded in transition results. Created 6 years, 9 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/heap-snapshot-generator.cc ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index 36c7e5a30a9f1a1795c54faa2c639b8f6b80f263..495c7273055e50ac77a242f511ed677b07e65d8d 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1167,9 +1167,7 @@ static bool LookupForWrite(Handle<JSObject> receiver,
// chain check. This avoids a double lookup, but requires us to pass in the
// receiver when trying to fetch extra information from the transition.
receiver->map()->LookupTransition(*holder, *name, lookup);
- if (!lookup->IsTransition()) return false;
- PropertyDetails target_details = lookup->GetTransitionDetails();
- if (target_details.IsReadOnly()) return false;
+ if (!lookup->IsTransition() || lookup->IsReadOnly()) return false;
// If the value that's being stored does not fit in the field that the
// instance would transition to, create a new transition that fits the value.
@@ -1178,7 +1176,7 @@ static bool LookupForWrite(Handle<JSObject> receiver,
// Ensure the instance and its map were migrated before trying to update the
// transition target.
ASSERT(!receiver->map()->is_deprecated());
- if (!value->FitsRepresentation(target_details.representation())) {
+ if (!lookup->CanHoldValue(value)) {
Handle<Map> target(lookup->GetTransitionTarget());
Map::GeneralizeRepresentation(
target, target->LastAdded(),
@@ -1327,93 +1325,94 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
Handle<JSObject> holder(lookup->holder());
// Handlers do not use strict mode.
StoreStubCompiler compiler(isolate(), SLOPPY, kind());
- switch (lookup->type()) {
- case FIELD:
- return compiler.CompileStoreField(receiver, lookup, name);
- case TRANSITION: {
- // Explicitly pass in the receiver map since LookupForWrite may have
- // stored something else than the receiver in the holder.
- Handle<Map> transition(lookup->GetTransitionTarget());
- PropertyDetails details = transition->GetLastDescriptorDetails();
-
- if (details.type() == CALLBACKS || details.attributes() != NONE) break;
+ if (lookup->IsTransition()) {
+ // Explicitly pass in the receiver map since LookupForWrite may have
+ // stored something else than the receiver in the holder.
+ Handle<Map> transition(lookup->GetTransitionTarget());
+ PropertyDetails details = lookup->GetPropertyDetails();
+ if (details.type() != CALLBACKS && details.attributes() == NONE) {
return compiler.CompileStoreTransition(
receiver, lookup, transition, name);
}
- case NORMAL:
- if (kind() == Code::KEYED_STORE_IC) break;
- if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) {
- // The stub generated for the global object picks the value directly
- // from the property cell. So the property must be directly on the
- // global object.
- Handle<GlobalObject> global = receiver->IsJSGlobalProxy()
- ? handle(GlobalObject::cast(receiver->GetPrototype()))
- : Handle<GlobalObject>::cast(receiver);
- Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
- Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
- StoreGlobalStub stub(
- union_type->IsConstant(), receiver->IsJSGlobalProxy());
- Handle<Code> code = stub.GetCodeCopyFromTemplate(
- isolate(), global, cell);
- // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
- HeapObject::UpdateMapCodeCache(receiver, name, code);
- return code;
- }
- ASSERT(holder.is_identical_to(receiver));
- return isolate()->builtins()->StoreIC_Normal();
- case CALLBACKS: {
- Handle<Object> callback(lookup->GetCallbackObject(), isolate());
- if (callback->IsExecutableAccessorInfo()) {
- Handle<ExecutableAccessorInfo> info =
- Handle<ExecutableAccessorInfo>::cast(callback);
- if (v8::ToCData<Address>(info->setter()) == 0) break;
- if (!holder->HasFastProperties()) break;
- if (!info->IsCompatibleReceiver(*receiver)) break;
- return compiler.CompileStoreCallback(receiver, holder, name, info);
- } else if (callback->IsAccessorPair()) {
- Handle<Object> setter(
- Handle<AccessorPair>::cast(callback)->setter(), isolate());
- if (!setter->IsJSFunction()) break;
- if (holder->IsGlobalObject()) break;
- if (!holder->HasFastProperties()) break;
- Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
- CallOptimization call_optimization(function);
- if (call_optimization.is_simple_api_call() &&
- call_optimization.IsCompatibleReceiver(receiver, holder)) {
- return compiler.CompileStoreCallback(
- receiver, holder, name, call_optimization);
+ } else {
+ switch (lookup->type()) {
+ case FIELD:
+ return compiler.CompileStoreField(receiver, lookup, name);
+ case NORMAL:
+ if (kind() == Code::KEYED_STORE_IC) break;
+ if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) {
+ // The stub generated for the global object picks the value directly
+ // from the property cell. So the property must be directly on the
+ // global object.
+ Handle<GlobalObject> global = receiver->IsJSGlobalProxy()
+ ? handle(GlobalObject::cast(receiver->GetPrototype()))
+ : Handle<GlobalObject>::cast(receiver);
+ Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
+ Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
+ StoreGlobalStub stub(
+ union_type->IsConstant(), receiver->IsJSGlobalProxy());
+ Handle<Code> code = stub.GetCodeCopyFromTemplate(
+ isolate(), global, cell);
+ // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
+ HeapObject::UpdateMapCodeCache(receiver, name, code);
+ return code;
+ }
+ ASSERT(holder.is_identical_to(receiver));
+ return isolate()->builtins()->StoreIC_Normal();
+ case CALLBACKS: {
+ Handle<Object> callback(lookup->GetCallbackObject(), isolate());
+ if (callback->IsExecutableAccessorInfo()) {
+ Handle<ExecutableAccessorInfo> info =
+ Handle<ExecutableAccessorInfo>::cast(callback);
+ if (v8::ToCData<Address>(info->setter()) == 0) break;
+ if (!holder->HasFastProperties()) break;
+ if (!info->IsCompatibleReceiver(*receiver)) break;
+ return compiler.CompileStoreCallback(receiver, holder, name, info);
+ } else if (callback->IsAccessorPair()) {
+ Handle<Object> setter(
+ Handle<AccessorPair>::cast(callback)->setter(), isolate());
+ if (!setter->IsJSFunction()) break;
+ if (holder->IsGlobalObject()) break;
+ if (!holder->HasFastProperties()) break;
+ Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
+ CallOptimization call_optimization(function);
+ if (call_optimization.is_simple_api_call() &&
+ call_optimization.IsCompatibleReceiver(receiver, holder)) {
+ return compiler.CompileStoreCallback(
+ receiver, holder, name, call_optimization);
+ }
+ return compiler.CompileStoreViaSetter(
+ receiver, holder, name, Handle<JSFunction>::cast(setter));
+ }
+ // TODO(dcarney): Handle correctly.
+ if (callback->IsDeclaredAccessorInfo()) break;
+ ASSERT(callback->IsForeign());
+
+ // Use specialized code for setting the length of arrays with fast
+ // properties. Slow properties might indicate redefinition of the length
+ // property.
+ if (receiver->IsJSArray() &&
+ name->Equals(isolate()->heap()->length_string()) &&
+ Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
+ receiver->HasFastProperties()) {
+ return compiler.CompileStoreArrayLength(receiver, lookup, name);
}
- return compiler.CompileStoreViaSetter(
- receiver, holder, name, Handle<JSFunction>::cast(setter));
- }
- // TODO(dcarney): Handle correctly.
- if (callback->IsDeclaredAccessorInfo()) break;
- ASSERT(callback->IsForeign());
- // Use specialized code for setting the length of arrays with fast
- // properties. Slow properties might indicate redefinition of the length
- // property.
- if (receiver->IsJSArray() &&
- name->Equals(isolate()->heap()->length_string()) &&
- Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
- receiver->HasFastProperties()) {
- return compiler.CompileStoreArrayLength(receiver, lookup, name);
+ // No IC support for old-style native accessors.
+ break;
}
-
- // No IC support for old-style native accessors.
- break;
+ case INTERCEPTOR:
+ if (kind() == Code::KEYED_STORE_IC) break;
+ ASSERT(HasInterceptorSetter(*holder));
+ return compiler.CompileStoreInterceptor(receiver, name);
+ case CONSTANT:
+ break;
+ case NONEXISTENT:
+ case HANDLER:
+ UNREACHABLE();
+ break;
}
- case INTERCEPTOR:
- if (kind() == Code::KEYED_STORE_IC) break;
- ASSERT(HasInterceptorSetter(*holder));
- return compiler.CompileStoreInterceptor(receiver, name);
- case CONSTANT:
- break;
- case NONEXISTENT:
- case HANDLER:
- UNREACHABLE();
- break;
}
return slow_stub();
}
« no previous file with comments | « src/heap-snapshot-generator.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698