Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index 36c7e5a30a9f1a1795c54faa2c639b8f6b80f263..6ffe192de42bdca98627984a8cf804799b48c0e8 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -435,6 +435,86 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) { |
} |
+void IC::RegisterWeakMapDependency(Handle<Code> stub) { |
+ if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic) { |
+ if (stub->is_weak_stub()) { |
+ MapHandleList maps; |
+ int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
+ for (RelocIterator it(*stub, mode_mask); !it.done(); it.next()) { |
+ if (it.rinfo()->target_object()->IsMap()) { |
+ Handle<Map> map(Map::cast(it.rinfo()->target_object())); |
+ if (stub->IsWeakObject(*map)) { |
+ maps.Add(map); |
+ } |
+ } |
+ } |
+#ifdef VERIFY_HEAP |
+ // This disables verification of weak embedded maps after full GC. |
+ // AddDependentCode can cause a GC, which would observe the state where |
+ // this code is not yet in the depended code lists of the embedded maps. |
+ NoWeakObjectVerificationScope disable_verification_of_objects; |
+#endif |
+ for (int i = 0; i < maps.length(); i++) { |
+ maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, stub); |
Toon Verwaest
2014/04/03 15:18:36
This means that all maps have 2 pointers to monomo
ulan
2014/04/03 15:40:26
As discussed offline, we can probably do that if l
|
+ } |
+ } |
+ } |
+} |
+ |
+ |
+Code* IC::MissBuiltin(Isolate* isolate, Code* stub) { |
+ switch (stub->kind()) { |
+ case Code::LOAD_IC: |
+ case Code::STORE_IC: |
+ case Code::KEYED_LOAD_IC: |
+ case Code::KEYED_STORE_IC: { |
+ return isolate->builtins()->builtin( |
+ BaseLoadStoreStubCompiler::MissBuiltin(stub->kind())); |
Toon Verwaest
2014/04/03 15:18:36
4-space indent
ulan
2014/04/03 15:40:26
Done.
|
+ } |
+ case Code::COMPARE_NIL_IC: { |
+ ExtraICState state = stub->extra_ic_state(); |
+ CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); |
+ stub.ClearState(); |
+ Code* code = NULL; |
+ CHECK(stub.FindCodeInCache(&code, isolate)); |
+ return code; |
+ } |
+ default: |
+ UNREACHABLE(); |
+ } |
+ return NULL; |
+} |
+ |
+ |
+void IC::InvalidateMapsAndHandlers(Code* stub) { |
+ ASSERT(stub->is_weak_stub()); |
+ Isolate* isolate = stub->GetIsolate(); |
+ Heap* heap = isolate->heap(); |
+ Code* miss = MissBuiltin(isolate, stub); |
+ Object* undefined = heap->undefined_value(); |
+ int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |
+ RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
+ // Set every map to undefined and every code target to the miss builtin. |
+ for (RelocIterator it(stub, mode_mask); !it.done(); it.next()) { |
+ RelocInfo::Mode mode = it.rinfo()->rmode(); |
+ if (mode == RelocInfo::EMBEDDED_OBJECT && |
+ it.rinfo()->target_object()->IsMap()) { |
+ it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER); |
+ } else if (mode == RelocInfo::CODE_TARGET) { |
+ Address address = it.rinfo()->pc(); |
+ Assembler::set_target_address_at( |
+ address, stub, miss->instruction_start()); |
+ if (heap->gc_state() == Heap::MARK_COMPACT) { |
+ heap->mark_compact_collector()->RecordCodeTargetPatch(address, miss); |
+ } else { |
+ heap->incremental_marking()->RecordCodeTargetPatch(address, miss); |
+ } |
+ } |
+ } |
+ CPU::FlushICache(stub->instruction_start(), stub->instruction_size()); |
+} |
+ |
+ |
void IC::Clear(Isolate* isolate, Address address, |
ConstantPoolArray* constant_pool) { |
Code* target = GetTargetAtAddress(address, constant_pool); |