Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 10125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10136 } | 10136 } |
| 10137 | 10137 |
| 10138 | 10138 |
| 10139 void SharedFunctionInfo::AddToOptimizedCodeMap( | 10139 void SharedFunctionInfo::AddToOptimizedCodeMap( |
| 10140 Handle<SharedFunctionInfo> shared, | 10140 Handle<SharedFunctionInfo> shared, |
| 10141 Handle<Context> native_context, | 10141 Handle<Context> native_context, |
| 10142 Handle<Code> code, | 10142 Handle<Code> code, |
| 10143 Handle<FixedArray> literals, | 10143 Handle<FixedArray> literals, |
| 10144 BailoutId osr_ast_id) { | 10144 BailoutId osr_ast_id) { |
| 10145 Isolate* isolate = shared->GetIsolate(); | 10145 Isolate* isolate = shared->GetIsolate(); |
| 10146 DCHECK(!shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); | 10146 DCHECK(code.is_null() || |
| 10147 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); | 10147 !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); |
| 10148 DCHECK(code.is_null() || code->kind() == Code::OPTIMIZED_FUNCTION); | |
| 10148 DCHECK(native_context->IsNativeContext()); | 10149 DCHECK(native_context->IsNativeContext()); |
| 10149 STATIC_ASSERT(kEntryLength == 4); | 10150 STATIC_ASSERT(kEntryLength == 4); |
| 10150 Handle<FixedArray> new_code_map; | 10151 Handle<FixedArray> new_code_map; |
| 10151 Handle<Object> value(shared->optimized_code_map(), isolate); | 10152 Handle<Object> value(shared->optimized_code_map(), isolate); |
| 10152 int old_length; | 10153 int old_length; |
| 10153 if (value->IsSmi()) { | 10154 if (value->IsSmi()) { |
| 10154 // No optimized code map. | 10155 // No optimized code map. |
| 10155 DCHECK_EQ(0, Smi::cast(*value)->value()); | 10156 DCHECK_EQ(0, Smi::cast(*value)->value()); |
| 10156 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); | 10157 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); |
| 10157 old_length = kEntriesStart; | 10158 old_length = kEntriesStart; |
| 10158 } else { | 10159 } else { |
| 10160 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value); | |
| 10161 int entry = | |
| 10162 shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); | |
| 10163 if (entry > kSharedCodeIndex) { | |
| 10164 // Found an existing context-specific entry, it must not contain any code. | |
| 10165 DCHECK(old_code_map->get(entry + kCachedCodeOffset) == nullptr); | |
| 10166 // Just set the code and literals to the entry. | |
| 10167 if (!code.is_null()) { | |
| 10168 old_code_map->set(entry + kCachedCodeOffset, *code); | |
| 10169 } | |
| 10170 old_code_map->set(entry + kLiteralsOffset, *literals); | |
| 10171 return; | |
| 10172 } | |
| 10173 | |
| 10159 // Copy old optimized code map and append one new entry. | 10174 // Copy old optimized code map and append one new entry. |
| 10160 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value); | |
| 10161 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( | 10175 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( |
| 10162 old_code_map, kEntryLength, TENURED); | 10176 old_code_map, kEntryLength, TENURED); |
| 10163 old_length = old_code_map->length(); | 10177 old_length = old_code_map->length(); |
| 10164 // Zap the old map to avoid any stale entries. Note that this is required | 10178 // Zap the old map to avoid any stale entries. Note that this is required |
| 10165 // for correctness because entries are being treated weakly by the GC. | 10179 // for correctness because entries are being treated weakly by the GC. |
| 10166 MemsetPointer(old_code_map->data_start(), isolate->heap()->the_hole_value(), | 10180 MemsetPointer(old_code_map->data_start(), isolate->heap()->the_hole_value(), |
| 10167 old_length); | 10181 old_length); |
| 10168 } | 10182 } |
| 10169 new_code_map->set(old_length + kContextOffset, *native_context); | 10183 new_code_map->set(old_length + kContextOffset, *native_context); |
| 10170 new_code_map->set(old_length + kCachedCodeOffset, *code); | 10184 new_code_map->set(old_length + kCachedCodeOffset, |
| 10185 code.is_null() ? nullptr : *code); | |
| 10171 new_code_map->set(old_length + kLiteralsOffset, *literals); | 10186 new_code_map->set(old_length + kLiteralsOffset, *literals); |
| 10172 new_code_map->set(old_length + kOsrAstIdOffset, | 10187 new_code_map->set(old_length + kOsrAstIdOffset, |
| 10173 Smi::FromInt(osr_ast_id.ToInt())); | 10188 Smi::FromInt(osr_ast_id.ToInt())); |
| 10174 | 10189 |
| 10175 #ifdef DEBUG | 10190 #ifdef DEBUG |
| 10176 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { | 10191 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { |
| 10177 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext()); | 10192 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext()); |
| 10178 DCHECK(new_code_map->get(i + kCachedCodeOffset)->IsCode()); | 10193 Object* code = new_code_map->get(i + kCachedCodeOffset); |
| 10179 DCHECK(Code::cast(new_code_map->get(i + kCachedCodeOffset))->kind() == | 10194 if (code != nullptr) { |
| 10180 Code::OPTIMIZED_FUNCTION); | 10195 DCHECK(code->IsCode()); |
| 10196 DCHECK(Code::cast(code)->kind() == Code::OPTIMIZED_FUNCTION); | |
| 10197 } | |
| 10181 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); | 10198 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); |
| 10182 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); | 10199 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); |
| 10183 } | 10200 } |
| 10184 #endif | 10201 #endif |
| 10185 shared->set_optimized_code_map(*new_code_map); | 10202 shared->set_optimized_code_map(*new_code_map); |
| 10186 } | 10203 } |
| 10187 | 10204 |
| 10188 | 10205 |
| 10189 void SharedFunctionInfo::ClearOptimizedCodeMap() { | 10206 void SharedFunctionInfo::ClearOptimizedCodeMap() { |
| 10190 FixedArray* code_map = FixedArray::cast(optimized_code_map()); | 10207 FixedArray* code_map = FixedArray::cast(optimized_code_map()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 10204 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, | 10221 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
| 10205 const char* reason) { | 10222 const char* reason) { |
| 10206 DisallowHeapAllocation no_gc; | 10223 DisallowHeapAllocation no_gc; |
| 10207 if (optimized_code_map()->IsSmi()) return; | 10224 if (optimized_code_map()->IsSmi()) return; |
| 10208 | 10225 |
| 10209 FixedArray* code_map = FixedArray::cast(optimized_code_map()); | 10226 FixedArray* code_map = FixedArray::cast(optimized_code_map()); |
| 10210 int dst = kEntriesStart; | 10227 int dst = kEntriesStart; |
| 10211 int length = code_map->length(); | 10228 int length = code_map->length(); |
| 10212 for (int src = kEntriesStart; src < length; src += kEntryLength) { | 10229 for (int src = kEntriesStart; src < length; src += kEntryLength) { |
| 10213 DCHECK(code_map->get(src)->IsNativeContext()); | 10230 DCHECK(code_map->get(src)->IsNativeContext()); |
| 10214 if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) { | 10231 if (code_map->get(src + kCachedCodeOffset) == optimized_code) { |
| 10215 // Evict the src entry by not copying it to the dst entry. | 10232 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value()); |
| 10216 if (FLAG_trace_opt) { | 10233 if (FLAG_trace_opt) { |
| 10217 PrintF("[evicting entry from optimizing code map (%s) for ", reason); | 10234 PrintF("[evicting entry from optimizing code map (%s) for ", reason); |
| 10218 ShortPrint(); | 10235 ShortPrint(); |
| 10219 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value()); | |
| 10220 if (osr.IsNone()) { | 10236 if (osr.IsNone()) { |
| 10221 PrintF("]\n"); | 10237 PrintF("]\n"); |
| 10222 } else { | 10238 } else { |
| 10223 PrintF(" (osr ast id %d)]\n", osr.ToInt()); | 10239 PrintF(" (osr ast id %d)]\n", osr.ToInt()); |
| 10224 } | 10240 } |
| 10225 } | 10241 } |
| 10226 } else { | 10242 if (!osr.IsNone()) { |
| 10227 // Keep the src entry by copying it to the dst entry. | 10243 // Evict the src entry by not copying it to the dst entry. |
| 10228 if (dst != src) { | 10244 continue; |
| 10229 code_map->set(dst + kContextOffset, | |
| 10230 code_map->get(src + kContextOffset)); | |
| 10231 code_map->set(dst + kCachedCodeOffset, | |
| 10232 code_map->get(src + kCachedCodeOffset)); | |
| 10233 code_map->set(dst + kLiteralsOffset, | |
| 10234 code_map->get(src + kLiteralsOffset)); | |
| 10235 code_map->set(dst + kOsrAstIdOffset, | |
| 10236 code_map->get(src + kOsrAstIdOffset)); | |
| 10237 } | 10245 } |
| 10238 dst += kEntryLength; | 10246 // In case of non-OSR entry just clear the code in order to proceed |
| 10247 // sharing literals. | |
| 10248 code_map->set(src + kCachedCodeOffset, static_cast<Code*>(nullptr)); | |
| 10239 } | 10249 } |
| 10250 | |
| 10251 // Keep the src entry by copying it to the dst entry. | |
| 10252 if (dst != src) { | |
| 10253 code_map->set(dst + kContextOffset, code_map->get(src + kContextOffset)); | |
| 10254 code_map->set(dst + kCachedCodeOffset, | |
| 10255 code_map->get(src + kCachedCodeOffset)); | |
| 10256 code_map->set(dst + kLiteralsOffset, | |
| 10257 code_map->get(src + kLiteralsOffset)); | |
| 10258 code_map->set(dst + kOsrAstIdOffset, | |
| 10259 code_map->get(src + kOsrAstIdOffset)); | |
| 10260 } | |
| 10261 dst += kEntryLength; | |
| 10240 } | 10262 } |
| 10241 if (code_map->get(kSharedCodeIndex) == optimized_code) { | 10263 if (code_map->get(kSharedCodeIndex) == optimized_code) { |
| 10242 // Evict context-independent code as well. | 10264 // Evict context-independent code as well. |
| 10243 code_map->set_undefined(kSharedCodeIndex); | 10265 code_map->set_undefined(kSharedCodeIndex); |
| 10244 if (FLAG_trace_opt) { | 10266 if (FLAG_trace_opt) { |
| 10245 PrintF("[evicting entry from optimizing code map (%s) for ", reason); | 10267 PrintF("[evicting entry from optimizing code map (%s) for ", reason); |
| 10246 ShortPrint(); | 10268 ShortPrint(); |
| 10247 PrintF(" (context-independent code)]\n"); | 10269 PrintF(" (context-independent code)]\n"); |
| 10248 } | 10270 } |
| 10249 } | 10271 } |
| (...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11258 opt_count() >= FLAG_max_opt_count) { | 11280 opt_count() >= FLAG_max_opt_count) { |
| 11259 // Re-enable optimizations if they were disabled due to opt_count limit. | 11281 // Re-enable optimizations if they were disabled due to opt_count limit. |
| 11260 set_optimization_disabled(false); | 11282 set_optimization_disabled(false); |
| 11261 } | 11283 } |
| 11262 set_opt_count(0); | 11284 set_opt_count(0); |
| 11263 set_deopt_count(0); | 11285 set_deopt_count(0); |
| 11264 } | 11286 } |
| 11265 } | 11287 } |
| 11266 | 11288 |
| 11267 | 11289 |
| 11268 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( | 11290 int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context, |
| 11269 Context* native_context, BailoutId osr_ast_id) { | 11291 BailoutId osr_ast_id) { |
| 11270 DisallowHeapAllocation no_gc; | 11292 DisallowHeapAllocation no_gc; |
| 11271 DCHECK(native_context->IsNativeContext()); | 11293 DCHECK(native_context->IsNativeContext()); |
| 11272 Object* value = optimized_code_map(); | 11294 Object* value = optimized_code_map(); |
| 11273 if (!value->IsSmi()) { | 11295 if (!value->IsSmi()) { |
| 11274 FixedArray* optimized_code_map = FixedArray::cast(value); | 11296 FixedArray* optimized_code_map = FixedArray::cast(value); |
| 11275 int length = optimized_code_map->length(); | 11297 int length = optimized_code_map->length(); |
| 11276 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); | 11298 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); |
| 11277 for (int i = kEntriesStart; i < length; i += kEntryLength) { | 11299 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
| 11278 if (optimized_code_map->get(i + kContextOffset) == native_context && | 11300 if (optimized_code_map->get(i + kContextOffset) == native_context && |
| 11279 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { | 11301 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { |
| 11280 return {Code::cast(optimized_code_map->get(i + kCachedCodeOffset)), | 11302 return i; |
| 11281 FixedArray::cast(optimized_code_map->get(i + kLiteralsOffset))}; | |
| 11282 } | 11303 } |
| 11283 } | 11304 } |
| 11284 Object* shared_code = optimized_code_map->get(kSharedCodeIndex); | 11305 Object* shared_code = optimized_code_map->get(kSharedCodeIndex); |
| 11285 if (shared_code->IsCode() && osr_ast_id.IsNone()) { | 11306 if (shared_code->IsCode() && osr_ast_id.IsNone()) { |
| 11286 return {Code::cast(shared_code), nullptr}; | 11307 return kSharedCodeIndex; |
| 11287 } | 11308 } |
| 11288 if (FLAG_trace_opt) { | 11309 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.
| |
| 11289 PrintF("[didn't find optimized code in optimized code map for "); | 11310 PrintF("[didn't find optimized code in optimized code map for "); |
| 11290 ShortPrint(); | 11311 ShortPrint(); |
| 11291 PrintF("]\n"); | 11312 PrintF("]\n"); |
| 11292 } | 11313 } |
| 11293 } | 11314 } |
| 11294 return {nullptr, nullptr}; | 11315 return -1; |
| 11295 } | 11316 } |
| 11296 | 11317 |
| 11297 | 11318 |
| 11319 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( | |
| 11320 Context* native_context, BailoutId osr_ast_id) { | |
| 11321 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); | |
| 11322 if (entry == kNotFound) return {nullptr, nullptr}; | |
| 11323 | |
| 11324 FixedArray* code_map = FixedArray::cast(optimized_code_map()); | |
| 11325 if (entry == kSharedCodeIndex) { | |
| 11326 return {Code::cast(code_map->get(kSharedCodeIndex)), nullptr}; | |
| 11327 } | |
| 11328 DCHECK_LE(entry + kEntryLength, code_map->length()); | |
| 11329 Object* code = code_map->get(entry + kCachedCodeOffset); | |
| 11330 return {code == nullptr ? nullptr : Code::cast(code), | |
| 11331 FixedArray::cast(code_map->get(entry + kLiteralsOffset))}; | |
| 11332 } | |
| 11333 | |
| 11334 | |
| 11298 #define DECLARE_TAG(ignore1, name, ignore2) name, | 11335 #define DECLARE_TAG(ignore1, name, ignore2) name, |
| 11299 const char* const VisitorSynchronization::kTags[ | 11336 const char* const VisitorSynchronization::kTags[ |
| 11300 VisitorSynchronization::kNumberOfSyncTags] = { | 11337 VisitorSynchronization::kNumberOfSyncTags] = { |
| 11301 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) | 11338 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) |
| 11302 }; | 11339 }; |
| 11303 #undef DECLARE_TAG | 11340 #undef DECLARE_TAG |
| 11304 | 11341 |
| 11305 | 11342 |
| 11306 #define DECLARE_TAG(ignore1, ignore2, name) name, | 11343 #define DECLARE_TAG(ignore1, ignore2, name) name, |
| 11307 const char* const VisitorSynchronization::kTagNames[ | 11344 const char* const VisitorSynchronization::kTagNames[ |
| (...skipping 5382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16690 if (cell->value() != *new_value) { | 16727 if (cell->value() != *new_value) { |
| 16691 cell->set_value(*new_value); | 16728 cell->set_value(*new_value); |
| 16692 Isolate* isolate = cell->GetIsolate(); | 16729 Isolate* isolate = cell->GetIsolate(); |
| 16693 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16730 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 16694 isolate, DependentCode::kPropertyCellChangedGroup); | 16731 isolate, DependentCode::kPropertyCellChangedGroup); |
| 16695 } | 16732 } |
| 16696 } | 16733 } |
| 16697 | 16734 |
| 16698 } // namespace internal | 16735 } // namespace internal |
| 16699 } // namespace v8 | 16736 } // namespace v8 |
| OLD | NEW |