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 |