Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 7db54aa811e7ce2ed260f4ec729675231fd830bd..d2fb4b763e28f9a1792c3ccbe68f7cf6a433dbb4 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -10143,8 +10143,9 @@ void SharedFunctionInfo::AddToOptimizedCodeMap( |
| Handle<FixedArray> literals, |
| BailoutId osr_ast_id) { |
| Isolate* isolate = shared->GetIsolate(); |
| - DCHECK(!shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); |
| - DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
| + DCHECK(code.is_null() || |
| + !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); |
| + DCHECK(code.is_null() || code->kind() == Code::OPTIMIZED_FUNCTION); |
| DCHECK(native_context->IsNativeContext()); |
| STATIC_ASSERT(kEntryLength == 4); |
| Handle<FixedArray> new_code_map; |
| @@ -10156,8 +10157,21 @@ void SharedFunctionInfo::AddToOptimizedCodeMap( |
| new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); |
| old_length = kEntriesStart; |
| } else { |
| - // Copy old optimized code map and append one new entry. |
| Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value); |
| + int entry = |
| + shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); |
| + if (entry > kSharedCodeIndex) { |
| + // Found an existing context-specific entry, it must not contain any code. |
| + DCHECK(old_code_map->get(entry + kCachedCodeOffset) == nullptr); |
| + // Just set the code and literals to the entry. |
| + if (!code.is_null()) { |
| + old_code_map->set(entry + kCachedCodeOffset, *code); |
| + } |
| + old_code_map->set(entry + kLiteralsOffset, *literals); |
| + return; |
| + } |
| + |
| + // Copy old optimized code map and append one new entry. |
| new_code_map = isolate->factory()->CopyFixedArrayAndGrow( |
| old_code_map, kEntryLength, TENURED); |
| old_length = old_code_map->length(); |
| @@ -10167,7 +10181,8 @@ void SharedFunctionInfo::AddToOptimizedCodeMap( |
| old_length); |
| } |
| new_code_map->set(old_length + kContextOffset, *native_context); |
| - new_code_map->set(old_length + kCachedCodeOffset, *code); |
| + new_code_map->set(old_length + kCachedCodeOffset, |
| + code.is_null() ? nullptr : *code); |
| new_code_map->set(old_length + kLiteralsOffset, *literals); |
| new_code_map->set(old_length + kOsrAstIdOffset, |
| Smi::FromInt(osr_ast_id.ToInt())); |
| @@ -10175,9 +10190,11 @@ void SharedFunctionInfo::AddToOptimizedCodeMap( |
| #ifdef DEBUG |
| for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { |
| DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext()); |
| - DCHECK(new_code_map->get(i + kCachedCodeOffset)->IsCode()); |
| - DCHECK(Code::cast(new_code_map->get(i + kCachedCodeOffset))->kind() == |
| - Code::OPTIMIZED_FUNCTION); |
| + Object* code = new_code_map->get(i + kCachedCodeOffset); |
| + if (code != nullptr) { |
| + DCHECK(code->IsCode()); |
| + DCHECK(Code::cast(code)->kind() == Code::OPTIMIZED_FUNCTION); |
| + } |
| DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); |
| DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); |
| } |
| @@ -10211,32 +10228,37 @@ void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
| int length = code_map->length(); |
| for (int src = kEntriesStart; src < length; src += kEntryLength) { |
| DCHECK(code_map->get(src)->IsNativeContext()); |
| - if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) { |
| - // Evict the src entry by not copying it to the dst entry. |
| + if (code_map->get(src + kCachedCodeOffset) == 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); |
| ShortPrint(); |
| - BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value()); |
| if (osr.IsNone()) { |
| PrintF("]\n"); |
| } else { |
| PrintF(" (osr ast id %d)]\n", osr.ToInt()); |
| } |
| } |
| - } else { |
| - // Keep the src entry by copying it to the dst entry. |
| - if (dst != src) { |
| - code_map->set(dst + kContextOffset, |
| - code_map->get(src + kContextOffset)); |
| - code_map->set(dst + kCachedCodeOffset, |
| - code_map->get(src + kCachedCodeOffset)); |
| - code_map->set(dst + kLiteralsOffset, |
| - code_map->get(src + kLiteralsOffset)); |
| - code_map->set(dst + kOsrAstIdOffset, |
| - code_map->get(src + kOsrAstIdOffset)); |
| + if (!osr.IsNone()) { |
| + // Evict the src entry by not copying it to the dst entry. |
| + continue; |
| } |
| - dst += kEntryLength; |
| + // In case of non-OSR entry just clear the code in order to proceed |
| + // sharing literals. |
| + code_map->set(src + kCachedCodeOffset, static_cast<Code*>(nullptr)); |
| + } |
| + |
| + // Keep the src entry by copying it to the dst entry. |
| + if (dst != src) { |
| + code_map->set(dst + kContextOffset, code_map->get(src + kContextOffset)); |
| + code_map->set(dst + kCachedCodeOffset, |
| + code_map->get(src + kCachedCodeOffset)); |
| + code_map->set(dst + kLiteralsOffset, |
| + code_map->get(src + kLiteralsOffset)); |
| + code_map->set(dst + kOsrAstIdOffset, |
| + code_map->get(src + kOsrAstIdOffset)); |
| } |
| + dst += kEntryLength; |
| } |
| if (code_map->get(kSharedCodeIndex) == optimized_code) { |
| // Evict context-independent code as well. |
| @@ -11265,8 +11287,8 @@ void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { |
| } |
| -CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
| - Context* native_context, BailoutId osr_ast_id) { |
| +int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context, |
| + BailoutId osr_ast_id) { |
| DisallowHeapAllocation no_gc; |
| DCHECK(native_context->IsNativeContext()); |
| Object* value = optimized_code_map(); |
| @@ -11277,13 +11299,12 @@ CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
| for (int i = kEntriesStart; i < length; i += kEntryLength) { |
| if (optimized_code_map->get(i + kContextOffset) == native_context && |
| optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { |
| - return {Code::cast(optimized_code_map->get(i + kCachedCodeOffset)), |
| - FixedArray::cast(optimized_code_map->get(i + kLiteralsOffset))}; |
| + return i; |
| } |
| } |
| Object* shared_code = optimized_code_map->get(kSharedCodeIndex); |
| if (shared_code->IsCode() && osr_ast_id.IsNone()) { |
| - return {Code::cast(shared_code), nullptr}; |
| + return kSharedCodeIndex; |
| } |
| if (FLAG_trace_opt) { |
|
Michael Starzinger
2015/09/22 10:57:34
This tracing will also be printed when adding new
Igor Sheludko
2015/09/22 12:58:11
Fixed.
|
| PrintF("[didn't find optimized code in optimized code map for "); |
| @@ -11291,7 +11312,23 @@ CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
| PrintF("]\n"); |
| } |
| } |
| - return {nullptr, nullptr}; |
| + return -1; |
| +} |
| + |
| + |
| +CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
| + Context* native_context, BailoutId osr_ast_id) { |
| + int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); |
| + if (entry == kNotFound) return {nullptr, nullptr}; |
| + |
| + FixedArray* code_map = FixedArray::cast(optimized_code_map()); |
| + if (entry == kSharedCodeIndex) { |
| + return {Code::cast(code_map->get(kSharedCodeIndex)), nullptr}; |
| + } |
| + DCHECK_LE(entry + kEntryLength, code_map->length()); |
| + Object* code = code_map->get(entry + kCachedCodeOffset); |
| + return {code == nullptr ? nullptr : Code::cast(code), |
| + FixedArray::cast(code_map->get(entry + kLiteralsOffset))}; |
| } |