Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index dbabe93e752e28cb3890e1f03455adabe697b545..b2559213e0243c4fadba1e5a309b712186fd9a7d 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -11415,7 +11415,8 @@ void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( |
| DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
| // Empty code maps are unsupported. |
| if (shared->OptimizedCodeMapIsCleared()) return; |
| - shared->optimized_code_map()->set(kSharedCodeIndex, *code); |
| + Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); |
| + shared->optimized_code_map()->set(kSharedCodeIndex, *cell); |
| } |
| @@ -11435,17 +11436,24 @@ void SharedFunctionInfo::AddToOptimizedCodeMap( |
| int entry; |
| if (shared->OptimizedCodeMapIsCleared()) { |
| new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); |
| + new_code_map->set(kSharedCodeIndex, *isolate->factory()->empty_weak_cell(), |
| + SKIP_WRITE_BARRIER); |
|
ulan
2015/11/27 10:03:18
Either
1) keep the write barrier
2) or add empty_w
mvstanton
2015/12/01 11:28:15
Nice! I'll do 2), because I'd like to believe I ca
|
| entry = kEntriesStart; |
| } else { |
| Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); |
| entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); |
| if (entry > kSharedCodeIndex) { |
| // Found an existing context-specific entry, it must not contain any code. |
| - DCHECK_EQ(isolate->heap()->undefined_value(), |
| - old_code_map->get(entry + kCachedCodeOffset)); |
| + DCHECK(WeakCell::cast(old_code_map->get(entry + kCachedCodeOffset)) |
| + ->cleared()); |
| // Just set the code and literals to the entry. |
| - old_code_map->set(entry + kCachedCodeOffset, *code); |
| - old_code_map->set(entry + kLiteralsOffset, *literals); |
| + Handle<WeakCell> code_cell = code->IsUndefined() |
| + ? isolate->factory()->empty_weak_cell() |
| + : isolate->factory()->NewWeakCell(code); |
| + Handle<WeakCell> literals_cell = |
| + isolate->factory()->NewWeakCell(literals); |
| + old_code_map->set(entry + kCachedCodeOffset, *code_cell); |
| + old_code_map->set(entry + kLiteralsOffset, *literals_cell); |
| return; |
| } |
| @@ -11458,20 +11466,28 @@ void SharedFunctionInfo::AddToOptimizedCodeMap( |
| if (shared->OptimizedCodeMapIsCleared()) return; |
| entry = old_code_map->length(); |
| } |
| - new_code_map->set(entry + kContextOffset, *native_context); |
| - new_code_map->set(entry + kCachedCodeOffset, *code); |
| - new_code_map->set(entry + kLiteralsOffset, *literals); |
| + |
| + Handle<WeakCell> code_cell = code->IsUndefined() |
| + ? isolate->factory()->empty_weak_cell() |
| + : isolate->factory()->NewWeakCell(code); |
| + Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); |
| + WeakCell* context_cell = native_context->self_weak_cell(); |
| + |
| + new_code_map->set(entry + kContextOffset, context_cell); |
| + new_code_map->set(entry + kCachedCodeOffset, *code_cell); |
| + new_code_map->set(entry + kLiteralsOffset, *literals_cell); |
| new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); |
| #ifdef DEBUG |
| for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { |
| - DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext()); |
| - Object* code = new_code_map->get(i + kCachedCodeOffset); |
| - if (code != isolate->heap()->undefined_value()) { |
| - DCHECK(code->IsCode()); |
| - DCHECK(Code::cast(code)->kind() == Code::OPTIMIZED_FUNCTION); |
| - } |
| - DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); |
| + WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); |
| + DCHECK(cell->cleared() || cell->value()->IsNativeContext()); |
| + cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); |
| + DCHECK(cell->cleared() || |
| + (cell->value()->IsCode() && |
| + Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); |
| + cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); |
| + DCHECK(cell->cleared() || cell->value()->IsFixedArray()); |
| DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); |
| } |
| #endif |
| @@ -11508,8 +11524,10 @@ void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
| int dst = kEntriesStart; |
| int length = code_map->length(); |
| for (int src = kEntriesStart; src < length; src += kEntryLength) { |
| - DCHECK(code_map->get(src)->IsNativeContext()); |
| - if (code_map->get(src + kCachedCodeOffset) == optimized_code) { |
| + DCHECK(WeakCell::cast(code_map->get(src))->cleared() || |
| + WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); |
| + if (WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == |
| + optimized_code) { |
| BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value()); |
| if (FLAG_trace_opt) { |
| PrintF("[evicting entry from optimizing code map (%s) for ", reason); |
| @@ -11526,7 +11544,8 @@ void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
| } |
| // In case of non-OSR entry just clear the code in order to proceed |
| // sharing literals. |
| - code_map->set_undefined(src + kCachedCodeOffset); |
| + code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), |
| + SKIP_WRITE_BARRIER); |
| } |
| // Keep the src entry by copying it to the dst entry. |
| @@ -11541,9 +11560,11 @@ void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
| } |
| dst += kEntryLength; |
| } |
| - if (code_map->get(kSharedCodeIndex) == optimized_code) { |
| + if (WeakCell::cast(code_map->get(kSharedCodeIndex))->value() == |
| + optimized_code) { |
| // Evict context-independent code as well. |
| - code_map->set_undefined(kSharedCodeIndex); |
| + code_map->set(kSharedCodeIndex, heap->empty_weak_cell(), |
| + SKIP_WRITE_BARRIER); |
| if (FLAG_trace_opt) { |
| PrintF("[evicting entry from optimizing code map (%s) for ", reason); |
| ShortPrint(); |
| @@ -11555,7 +11576,7 @@ void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
| heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(code_map, |
| length - dst); |
| if (code_map->length() == kEntriesStart && |
| - code_map->get(kSharedCodeIndex)->IsUndefined()) { |
| + WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { |
| ClearOptimizedCodeMap(); |
| } |
| } |
| @@ -11570,7 +11591,7 @@ void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { |
| GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, |
| shrink_by); |
| if (code_map->length() == kEntriesStart && |
| - code_map->get(kSharedCodeIndex)->IsUndefined()) { |
| + WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { |
| ClearOptimizedCodeMap(); |
| } |
| } |
| @@ -12795,12 +12816,14 @@ int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context, |
| int length = optimized_code_map->length(); |
| Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); |
| for (int i = kEntriesStart; i < length; i += kEntryLength) { |
| - if (optimized_code_map->get(i + kContextOffset) == native_context && |
| + if (WeakCell::cast(optimized_code_map->get(i + kContextOffset)) |
| + ->value() == native_context && |
| optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { |
| return i; |
| } |
| } |
| - Object* shared_code = optimized_code_map->get(kSharedCodeIndex); |
| + Object* shared_code = |
| + WeakCell::cast(optimized_code_map->get(kSharedCodeIndex))->value(); |
| if (shared_code->IsCode() && osr_ast_id.IsNone()) { |
| return kSharedCodeIndex; |
| } |
| @@ -12816,13 +12839,22 @@ CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
| if (entry != kNotFound) { |
| FixedArray* code_map = optimized_code_map(); |
| if (entry == kSharedCodeIndex) { |
| - result = {Code::cast(code_map->get(kSharedCodeIndex)), nullptr}; |
| - |
| + // We know the weak cell isn't cleared because we made sure of it in |
| + // SearchOptimizedCodeMapEntry and performed no allocations since that |
| + // call. |
| + result = { |
| + Code::cast(WeakCell::cast(code_map->get(kSharedCodeIndex))->value()), |
| + nullptr}; |
| } else { |
| DCHECK_LE(entry + kEntryLength, code_map->length()); |
| - Object* code = code_map->get(entry + kCachedCodeOffset); |
| - result = {code->IsUndefined() ? nullptr : Code::cast(code), |
| - LiteralsArray::cast(code_map->get(entry + kLiteralsOffset))}; |
| + WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); |
| + WeakCell* literals_cell = |
| + WeakCell::cast(code_map->get(entry + kLiteralsOffset)); |
| + |
| + result = {cell->cleared() ? nullptr : Code::cast(cell->value()), |
| + literals_cell->cleared() |
| + ? nullptr |
| + : LiteralsArray::cast(literals_cell->value())}; |
| } |
| } |
| if (FLAG_trace_opt && !OptimizedCodeMapIsCleared() && |