| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 0e87e5121a6ad77252f8bf8cea8f3eeabcb68867..a9477f4d818b94696245e54895c2232904393814 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -1629,79 +1629,40 @@ MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
|
| return generic_stub;
|
| }
|
|
|
| - // TODO(1385): Currently MEGAMORPHIC stubs are cached in the receiver map stub
|
| - // cache, but that can put receiver types together from unrelated call sites
|
| - // into the same stub--they always handle the union of all receiver maps seen
|
| - // at all call sites involving the receiver map. This is only an
|
| - // approximation: ideally, there would be a global cache that mapped sets of
|
| - // receiver maps to MEGAMORPHIC stubs. The complexity of the MEGAMORPHIC stub
|
| - // computation also leads to direct manipulation of the stub cache from the IC
|
| - // code, which the global cache solution would avoid.
|
| - Code::Kind kind = this->kind();
|
| - Code::Flags flags = Code::ComputeFlags(kind,
|
| - NOT_IN_LOOP,
|
| - MEGAMORPHIC,
|
| - strict_mode);
|
| - String* megamorphic_name = GetStubNameForCache(MEGAMORPHIC);
|
| - Object* maybe_cached_stub = receiver->map()->FindInCodeCache(megamorphic_name,
|
| - flags);
|
| -
|
| - // Create a set of all receiver maps that have been seen at the IC call site
|
| - // and those seen by the MEGAMORPHIC cached stub, if that's the stub that's
|
| - // been selected.
|
| - MapList receiver_maps;
|
| - if (!maybe_cached_stub->IsUndefined()) {
|
| - GetReceiverMapsForStub(Code::cast(maybe_cached_stub), &receiver_maps);
|
| - }
|
| - bool added_map = false;
|
| - for (int i = 0; i < target_receiver_maps.length(); ++i) {
|
| - if (AddOneReceiverMapIfMissing(&receiver_maps,
|
| - target_receiver_maps.at(i))) {
|
| - added_map = true;
|
| - }
|
| - }
|
| - ASSERT(receiver_maps.length() > 0);
|
| -
|
| - // If the maximum number of receiver maps has been exceeded, use the Generic
|
| + // If the maximum number of receiver maps has been exceeded, use the generic
|
| // version of the IC.
|
| - if (receiver_maps.length() > KeyedIC::kMaxKeyedPolymorphism) {
|
| + if (target_receiver_maps.length() > KeyedIC::kMaxKeyedPolymorphism) {
|
| return generic_stub;
|
| }
|
|
|
| - // If no maps have been seen at the call site that aren't in the cached
|
| - // stub, then use it.
|
| - if (!added_map) {
|
| - ASSERT(!maybe_cached_stub->IsUndefined());
|
| + PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache();
|
| + Code::Flags flags = Code::ComputeFlags(this->kind(),
|
| + NOT_IN_LOOP,
|
| + MEGAMORPHIC,
|
| + strict_mode);
|
| + Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags);
|
| + // If there is a cached stub, use it.
|
| + if (!maybe_cached_stub->IsUndefined()) {
|
| ASSERT(maybe_cached_stub->IsCode());
|
| return Code::cast(maybe_cached_stub);
|
| }
|
| -
|
| - // Lookup all of the receiver maps in the cache, they should all already
|
| - // have MONOMORPHIC stubs.
|
| - CodeList handler_ics(KeyedIC::kMaxKeyedPolymorphism);
|
| - for (int current = 0; current < receiver_maps.length(); ++current) {
|
| - Map* receiver_map(receiver_maps.at(current));
|
| + // Collect MONOMORPHIC stubs for all target_receiver_maps.
|
| + CodeList handler_ics(target_receiver_maps.length());
|
| + for (int i = 0; i < target_receiver_maps.length(); ++i) {
|
| + Map* receiver_map(target_receiver_maps.at(i));
|
| MaybeObject* maybe_cached_stub = ComputeMonomorphicStubWithoutMapCheck(
|
| - receiver_map,
|
| - strict_mode,
|
| - generic_stub);
|
| + receiver_map, strict_mode, generic_stub);
|
| Code* cached_stub;
|
| - if (!maybe_cached_stub->To(&cached_stub)) {
|
| - return maybe_cached_stub;
|
| - }
|
| + if (!maybe_cached_stub->To(&cached_stub)) return maybe_cached_stub;
|
| handler_ics.Add(cached_stub);
|
| }
|
| -
|
| - Code* stub;
|
| // Build the MEGAMORPHIC stub.
|
| - maybe_stub = ConstructMegamorphicStub(&receiver_maps,
|
| + Code* stub;
|
| + maybe_stub = ConstructMegamorphicStub(&target_receiver_maps,
|
| &handler_ics,
|
| strict_mode);
|
| if (!maybe_stub->To(&stub)) return maybe_stub;
|
| -
|
| - MaybeObject* maybe_update = receiver->UpdateMapCodeCache(
|
| - megamorphic_name,
|
| - stub);
|
| + MaybeObject* maybe_update = cache->Update(&target_receiver_maps, flags, stub);
|
| if (maybe_update->IsFailure()) return maybe_update;
|
| return stub;
|
| }
|
|
|