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

Unified Diff: src/ic.cc

Issue 71163006: Merge bleeding_edge r17376:17693. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Fix all.gyp Created 7 years, 1 month 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/ia32/stub-cache-ia32.cc ('k') | src/incremental-marking.cc » ('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 4bff543a733305ec33c966e5a890195013e538c5..640b188ab23bb1b62b59b5f9458ea6b811660f4e 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -270,8 +270,6 @@ bool CallIC::TryUpdateExtraICState(LookupResult* lookup,
bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
Handle<String> name) {
- DisallowHeapAllocation no_gc;
-
if (target()->is_call_stub()) {
LookupResult lookup(isolate());
LookupForRead(receiver, name, &lookup);
@@ -768,12 +766,13 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
// Bail out if we didn't find a result.
if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
- // Compute the number of arguments.
- Handle<Code> code;
- code = state() == UNINITIALIZED
- ? pre_monomorphic_stub()
- : ComputeMonomorphicStub(lookup, object, name);
+ if (state() == UNINITIALIZED) {
+ set_target(*pre_monomorphic_stub());
+ TRACE_IC("CallIC", name);
+ return;
+ }
+ Handle<Code> code = ComputeMonomorphicStub(lookup, object, name);
// If there's no appropriate stub we simply avoid updating the caches.
// TODO(verwaest): Install a slow fallback in this case to avoid not learning,
// and deopting Crankshaft code.
@@ -954,39 +953,36 @@ bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
Handle<String> name,
Handle<Code> code) {
if (!code->is_handler()) return false;
-
MapHandleList receiver_maps;
CodeHandleList handlers;
int number_of_valid_maps;
int handler_to_overwrite = -1;
Handle<Map> new_receiver_map(receiver->map());
- {
- DisallowHeapAllocation no_gc;
- target()->FindAllMaps(&receiver_maps);
- int number_of_maps = receiver_maps.length();
- number_of_valid_maps = number_of_maps;
-
- for (int i = 0; i < number_of_maps; i++) {
- Handle<Map> map = receiver_maps.at(i);
- // Filter out deprecated maps to ensure its instances get migrated.
- if (map->is_deprecated()) {
- number_of_valid_maps--;
- // If the receiver map is already in the polymorphic IC, this indicates
- // there was a prototoype chain failure. In that case, just overwrite the
- // handler.
- } else if (map.is_identical_to(new_receiver_map)) {
- number_of_valid_maps--;
- handler_to_overwrite = i;
- }
+
+ target()->FindAllMaps(&receiver_maps);
+ int number_of_maps = receiver_maps.length();
+ number_of_valid_maps = number_of_maps;
+
+ for (int i = 0; i < number_of_maps; i++) {
+ Handle<Map> map = receiver_maps.at(i);
+ // Filter out deprecated maps to ensure its instances get migrated.
+ if (map->is_deprecated()) {
+ number_of_valid_maps--;
+ // If the receiver map is already in the polymorphic IC, this indicates
+ // there was a prototoype chain failure. In that case, just overwrite the
+ // handler.
+ } else if (map.is_identical_to(new_receiver_map)) {
+ number_of_valid_maps--;
+ handler_to_overwrite = i;
}
+ }
- if (number_of_valid_maps >= 4) return false;
- if (number_of_maps == 0) return false;
+ if (number_of_valid_maps >= 4) return false;
+ if (number_of_maps == 0) return false;
- if (!target()->FindHandlers(&handlers, receiver_maps.length())) {
- return false;
- }
+ if (!target()->FindHandlers(&handlers, receiver_maps.length())) {
+ return false;
}
number_of_valid_maps++;
@@ -1017,11 +1013,8 @@ void IC::UpdateMonomorphicIC(Handle<HeapObject> receiver,
void IC::CopyICToMegamorphicCache(Handle<String> name) {
MapHandleList receiver_maps;
CodeHandleList handlers;
- {
- DisallowHeapAllocation no_gc;
- target()->FindAllMaps(&receiver_maps);
- if (!target()->FindHandlers(&handlers, receiver_maps.length())) return;
- }
+ target()->FindAllMaps(&receiver_maps);
+ if (!target()->FindHandlers(&handlers, receiver_maps.length())) return;
for (int i = 0; i < receiver_maps.length(); i++) {
UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
}
@@ -1029,8 +1022,6 @@ void IC::CopyICToMegamorphicCache(Handle<String> name) {
bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
- DisallowHeapAllocation no_allocation;
-
Map* current_map = target()->FindFirstMap();
ElementsKind receiver_elements_kind = receiver_map->elements_kind();
bool more_general_transition =
@@ -1061,43 +1052,26 @@ void IC::PatchCache(Handle<HeapObject> receiver,
!target().is_identical_to(code));
if (!target()->is_keyed_stub()) {
bool is_same_handler = false;
- {
- DisallowHeapAllocation no_allocation;
- Code* old_handler = target()->FindFirstHandler();
- is_same_handler = old_handler == *code;
- }
- if (is_same_handler
- && IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
+ Code* old_handler = target()->FindFirstHandler();
+ is_same_handler = old_handler == *code;
+
+ if (is_same_handler &&
+ IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
UpdateMonomorphicIC(receiver, code, name);
break;
}
- if (UpdatePolymorphicIC(receiver, name, code)) {
- break;
- }
-
+ }
+ // Fall through.
+ case POLYMORPHIC:
+ if (!target()->is_keyed_stub()) {
+ if (UpdatePolymorphicIC(receiver, name, code)) break;
CopyICToMegamorphicCache(name);
}
-
- UpdateMegamorphicCache(receiver->map(), *name, *code);
set_target(*megamorphic_stub());
- break;
+ // Fall through.
case MEGAMORPHIC:
UpdateMegamorphicCache(receiver->map(), *name, *code);
break;
- case POLYMORPHIC:
- if (target()->is_keyed_stub()) {
- // When trying to patch a polymorphic keyed stub with anything other
- // than another polymorphic stub, go generic.
- set_target(*generic_stub());
- } else {
- if (UpdatePolymorphicIC(receiver, name, code)) {
- break;
- }
- CopyICToMegamorphicCache(name);
- UpdateMegamorphicCache(receiver->map(), *name, *code);
- set_target(*megamorphic_stub());
- }
- break;
case DEBUG_STUB:
break;
case GENERIC:
@@ -1119,6 +1093,7 @@ Handle<Code> LoadIC::SimpleFieldLoad(int offset,
}
}
+
void LoadIC::UpdateCaches(LookupResult* lookup,
Handle<Object> object,
Handle<String> name) {
@@ -1133,7 +1108,9 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
// This is the first time we execute this inline cache.
// Set the target to the pre monomorphic stub to delay
// setting the monomorphic state.
- code = pre_monomorphic_stub();
+ set_target(*pre_monomorphic_stub());
+ TRACE_IC("LoadIC", name);
+ return;
} else if (!lookup->IsCacheable()) {
// Bail out if the result is not cacheable.
code = slow_stub();
@@ -1175,8 +1152,9 @@ Handle<Code> IC::ComputeHandler(LookupResult* lookup,
if (!code.is_null()) return code;
code = CompileHandler(lookup, receiver, name, value);
+ ASSERT(code->is_handler());
- if (code->is_handler() && code->type() != Code::NORMAL) {
+ if (code->type() != Code::NORMAL) {
HeapObject::UpdateMapCodeCache(receiver, name, code);
}
@@ -1215,9 +1193,11 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
Handle<PropertyCell> cell(
global->GetPropertyCell(lookup), isolate());
- // TODO(verwaest): Turn into a handler.
- return isolate()->stub_cache()->ComputeLoadGlobal(
- name, receiver, global, cell, lookup->IsDontDelete());
+ Handle<Code> code = compiler.CompileLoadGlobal(
+ receiver, global, cell, name, lookup->IsDontDelete());
+ // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
+ HeapObject::UpdateMapCodeCache(receiver, name, code);
+ return code;
}
// There is only one shared stub for loading normalized
// properties. It does not traverse the prototype chain, so the
@@ -1632,11 +1612,15 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
// from the property cell. So the property must be directly on the
// global object.
Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
- Handle<PropertyCell> cell(
- global->GetPropertyCell(lookup), isolate());
- // TODO(verwaest): Turn into a handler.
- return isolate()->stub_cache()->ComputeStoreGlobal(
- name, global, cell, value, strict_mode());
+ Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
+ Handle<Type> union_type = PropertyCell::UpdatedType(cell, value);
+ StoreGlobalStub stub(strict_mode(), union_type->IsConstant());
+
+ Handle<Code> code = stub.GetCodeCopyFromTemplate(
+ isolate(), receiver->map(), *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 strict_mode() == kStrictMode
@@ -1936,8 +1920,13 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
Handle<Object> value,
ICMissMode miss_mode) {
if (MigrateDeprecated(object)) {
- return Runtime::SetObjectPropertyOrFail(
- isolate(), object , key, value, NONE, strict_mode());
+ Handle<Object> result = Runtime::SetObjectProperty(isolate(), object,
+ key,
+ value,
+ NONE,
+ strict_mode());
+ RETURN_IF_EMPTY_HANDLE(isolate(), result);
+ return *result;
}
// Check for values that can be converted into an internalized string directly
@@ -1976,10 +1965,16 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
isolate()->heap()->non_strict_arguments_elements_map()) {
stub = non_strict_arguments_stub();
} else if (key_is_smi_like &&
- (!target().is_identical_to(non_strict_arguments_stub()))) {
- KeyedAccessStoreMode store_mode =
- GetStoreMode(receiver, key, value);
- stub = StoreElementStub(receiver, store_mode);
+ !(target().is_identical_to(non_strict_arguments_stub()))) {
+ // We should go generic if receiver isn't a dictionary, but our
+ // prototype chain does have dictionary elements. This ensures that
+ // other non-dictionary receivers in the polymorphic case benefit
+ // from fast path keyed stores.
+ if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
+ KeyedAccessStoreMode store_mode =
+ GetStoreMode(receiver, key, value);
+ stub = StoreElementStub(receiver, store_mode);
+ }
}
}
}
@@ -1996,8 +1991,12 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
}
if (maybe_object) return maybe_object;
- return Runtime::SetObjectPropertyOrFail(
- isolate(), object , key, value, NONE, strict_mode());
+ Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, key,
+ value,
+ NONE,
+ strict_mode());
+ RETURN_IF_EMPTY_HANDLE(isolate(), result);
+ return *result;
}
@@ -2228,12 +2227,12 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) {
Handle<Object> key = args.at<Object>(1);
Handle<Object> value = args.at<Object>(2);
StrictModeFlag strict_mode = ic.strict_mode();
- return Runtime::SetObjectProperty(isolate,
- object,
- key,
- value,
- NONE,
- strict_mode);
+ Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
+ value,
+ NONE,
+ strict_mode);
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
@@ -2245,12 +2244,12 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) {
Handle<Object> key = args.at<Object>(1);
Handle<Object> value = args.at<Object>(2);
StrictModeFlag strict_mode = ic.strict_mode();
- return Runtime::SetObjectProperty(isolate,
- object,
- key,
- value,
- NONE,
- strict_mode);
+ Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
+ value,
+ NONE,
+ strict_mode);
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
@@ -2270,15 +2269,20 @@ RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) {
ASSERT(args.length() == 4);
KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
Handle<Object> value = args.at<Object>(0);
+ Handle<Map> map = args.at<Map>(1);
Handle<Object> key = args.at<Object>(2);
Handle<Object> object = args.at<Object>(3);
StrictModeFlag strict_mode = ic.strict_mode();
- return Runtime::SetObjectProperty(isolate,
- object,
- key,
- value,
- NONE,
- strict_mode);
+ if (object->IsJSObject()) {
+ JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
+ map->elements_kind());
+ }
+ Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
+ value,
+ NONE,
+ strict_mode);
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
@@ -2306,6 +2310,7 @@ MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) {
right_type->Maybe(Type::Smi());
Maybe<Handle<Object> > result = stub.Result(left, right, isolate());
+ if (!result.has_value) return Failure::Exception();
#ifdef DEBUG
if (FLAG_trace_ic) {
@@ -2346,9 +2351,8 @@ MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) {
PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK);
}
- return result.has_value
- ? static_cast<MaybeObject*>(*result.value)
- : Failure::Exception();
+ ASSERT(result.has_value);
+ return static_cast<MaybeObject*>(*result.value);
}
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/incremental-marking.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698