OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/ast.h" | 7 #include "src/ast.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { | 74 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { |
75 Handle<Object> maybe_code = GetInfo(id); | 75 Handle<Object> maybe_code = GetInfo(id); |
76 if (maybe_code->IsCode()) { | 76 if (maybe_code->IsCode()) { |
77 Handle<Code> code = Handle<Code>::cast(maybe_code); | 77 Handle<Code> code = Handle<Code>::cast(maybe_code); |
78 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; | 78 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; |
79 } | 79 } |
80 return false; | 80 return false; |
81 } | 81 } |
82 | 82 |
83 | 83 |
84 bool TypeFeedbackOracle::LoadIsUninitialized(FeedbackVectorICSlot slot) { | |
85 Code::Kind kind = feedback_vector_->GetKind(slot); | |
86 if (kind == Code::LOAD_IC) { | |
87 LoadICNexus nexus(feedback_vector_, slot); | |
88 return nexus.StateFromFeedback() == UNINITIALIZED; | |
89 } else if (kind == Code::KEYED_LOAD_IC) { | |
90 KeyedLoadICNexus nexus(feedback_vector_, slot); | |
91 return nexus.StateFromFeedback() == UNINITIALIZED; | |
92 } else if (kind == Code::NUMBER_OF_KINDS) { | |
93 // Code::NUMBER_OF_KINDS indicates a slot that was never even compiled | |
94 // in full code. | |
95 return true; | |
96 } | |
97 | |
98 return false; | |
99 } | |
100 | |
101 | |
84 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { | 102 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { |
85 Handle<Object> maybe_code = GetInfo(ast_id); | 103 Handle<Object> maybe_code = GetInfo(ast_id); |
86 if (!maybe_code->IsCode()) return false; | 104 if (!maybe_code->IsCode()) return false; |
87 Handle<Code> code = Handle<Code>::cast(maybe_code); | 105 Handle<Code> code = Handle<Code>::cast(maybe_code); |
88 return code->ic_state() == UNINITIALIZED; | 106 return code->ic_state() == UNINITIALIZED; |
89 } | 107 } |
90 | 108 |
91 | 109 |
92 bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) { | 110 bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) { |
93 Handle<Object> value = GetInfo(slot); | 111 Handle<Object> value = GetInfo(slot); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 | 288 |
271 void TypeFeedbackOracle::PropertyReceiverTypes(TypeFeedbackId id, | 289 void TypeFeedbackOracle::PropertyReceiverTypes(TypeFeedbackId id, |
272 Handle<String> name, | 290 Handle<String> name, |
273 SmallMapList* receiver_types) { | 291 SmallMapList* receiver_types) { |
274 receiver_types->Clear(); | 292 receiver_types->Clear(); |
275 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 293 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
276 CollectReceiverTypes(id, name, flags, receiver_types); | 294 CollectReceiverTypes(id, name, flags, receiver_types); |
277 } | 295 } |
278 | 296 |
279 | 297 |
298 bool TypeFeedbackOracle::HasOnlyStringMaps(SmallMapList* receiver_types) { | |
299 bool all_strings = receiver_types->length() > 0; | |
300 for (int i = 0; i < receiver_types->length(); i++) { | |
301 all_strings &= receiver_types->at(i)->IsStringMap(); | |
302 } | |
303 return all_strings; | |
304 } | |
305 | |
306 | |
280 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( | 307 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( |
281 TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) { | 308 TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) { |
282 receiver_types->Clear(); | 309 receiver_types->Clear(); |
283 CollectReceiverTypes(id, receiver_types); | 310 CollectReceiverTypes(id, receiver_types); |
284 | 311 |
285 // Are all the receiver maps string maps? | 312 // Are all the receiver maps string maps? |
Jakob Kummerow
2014/11/26 15:14:15
I think this comment is now subsumed by the descri
mvstanton
2014/11/27 13:09:26
Done.
| |
286 bool all_strings = receiver_types->length() > 0; | 313 *is_string = HasOnlyStringMaps(receiver_types); |
287 for (int i = 0; i < receiver_types->length(); i++) { | |
288 all_strings &= receiver_types->at(i)->IsStringMap(); | |
289 } | |
290 *is_string = all_strings; | |
291 } | 314 } |
292 | 315 |
293 | 316 |
317 void TypeFeedbackOracle::PropertyReceiverTypes(FeedbackVectorICSlot slot, | |
318 Handle<String> name, | |
319 SmallMapList* receiver_types) { | |
320 receiver_types->Clear(); | |
321 LoadICNexus nexus(feedback_vector_, slot); | |
322 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | |
323 CollectReceiverTypes(&nexus, name, flags, receiver_types); | |
324 } | |
325 | |
326 | |
327 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( | |
328 FeedbackVectorICSlot slot, SmallMapList* receiver_types, bool* is_string) { | |
329 receiver_types->Clear(); | |
330 KeyedLoadICNexus nexus(feedback_vector_, slot); | |
331 CollectReceiverTypes<FeedbackNexus>(&nexus, receiver_types); | |
332 | |
333 // Are all the receiver maps string maps? | |
Jakob Kummerow
2014/11/26 15:14:15
again
mvstanton
2014/11/27 13:09:26
Done.
| |
334 *is_string = HasOnlyStringMaps(receiver_types); | |
335 } | |
336 | |
337 | |
294 void TypeFeedbackOracle::AssignmentReceiverTypes( | 338 void TypeFeedbackOracle::AssignmentReceiverTypes( |
295 TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) { | 339 TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) { |
296 receiver_types->Clear(); | 340 receiver_types->Clear(); |
297 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 341 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); |
298 CollectReceiverTypes(id, name, flags, receiver_types); | 342 CollectReceiverTypes(id, name, flags, receiver_types); |
299 } | 343 } |
300 | 344 |
301 | 345 |
302 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( | 346 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( |
303 TypeFeedbackId id, SmallMapList* receiver_types, | 347 TypeFeedbackId id, SmallMapList* receiver_types, |
(...skipping 13 matching lines...) Expand all Loading... | |
317 | 361 |
318 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 362 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, |
319 Handle<String> name, | 363 Handle<String> name, |
320 Code::Flags flags, | 364 Code::Flags flags, |
321 SmallMapList* types) { | 365 SmallMapList* types) { |
322 Handle<Object> object = GetInfo(ast_id); | 366 Handle<Object> object = GetInfo(ast_id); |
323 if (object->IsUndefined() || object->IsSmi()) return; | 367 if (object->IsUndefined() || object->IsSmi()) return; |
324 | 368 |
325 DCHECK(object->IsCode()); | 369 DCHECK(object->IsCode()); |
326 Handle<Code> code(Handle<Code>::cast(object)); | 370 Handle<Code> code(Handle<Code>::cast(object)); |
371 CollectReceiverTypes<Code>(*code, name, flags, types); | |
372 } | |
327 | 373 |
374 | |
375 template <class T> | |
376 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, Handle<String> name, | |
377 Code::Flags flags, | |
378 SmallMapList* types) { | |
328 if (FLAG_collect_megamorphic_maps_from_stub_cache && | 379 if (FLAG_collect_megamorphic_maps_from_stub_cache && |
329 code->ic_state() == MEGAMORPHIC) { | 380 obj->ic_state() == MEGAMORPHIC) { |
330 types->Reserve(4, zone()); | 381 types->Reserve(4, zone()); |
331 isolate()->stub_cache()->CollectMatchingMaps( | 382 isolate()->stub_cache()->CollectMatchingMaps( |
332 types, name, flags, native_context_, zone()); | 383 types, name, flags, native_context_, zone()); |
333 } else { | 384 } else { |
334 CollectReceiverTypes(ast_id, types); | 385 CollectReceiverTypes<T>(obj, types); |
335 } | 386 } |
336 } | 387 } |
337 | 388 |
338 | 389 |
339 // Check if a map originates from a given native context. We use this | 390 // Check if a map originates from a given native context. We use this |
340 // information to filter out maps from different context to avoid | 391 // information to filter out maps from different context to avoid |
341 // retaining objects from different tabs in Chrome via optimized code. | 392 // retaining objects from different tabs in Chrome via optimized code. |
342 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map, | 393 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map, |
343 Context* native_context) { | 394 Context* native_context) { |
344 Object* constructor = NULL; | 395 Object* constructor = NULL; |
(...skipping 23 matching lines...) Expand all Loading... | |
368 return function->context()->global_object() != native_context->global_object() | 419 return function->context()->global_object() != native_context->global_object() |
369 && function->context()->global_object() != native_context->builtins(); | 420 && function->context()->global_object() != native_context->builtins(); |
370 } | 421 } |
371 | 422 |
372 | 423 |
373 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 424 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, |
374 SmallMapList* types) { | 425 SmallMapList* types) { |
375 Handle<Object> object = GetInfo(ast_id); | 426 Handle<Object> object = GetInfo(ast_id); |
376 if (!object->IsCode()) return; | 427 if (!object->IsCode()) return; |
377 Handle<Code> code = Handle<Code>::cast(object); | 428 Handle<Code> code = Handle<Code>::cast(object); |
429 CollectReceiverTypes<Code>(*code, types); | |
430 } | |
431 | |
432 | |
433 template <class T> | |
434 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) { | |
378 MapHandleList maps; | 435 MapHandleList maps; |
379 if (code->ic_state() == MONOMORPHIC) { | 436 if (obj->ic_state() == MONOMORPHIC) { |
380 Map* map = code->FindFirstMap(); | 437 Map* map = obj->FindFirstMap(); |
381 if (map != NULL) maps.Add(handle(map)); | 438 if (map != NULL) maps.Add(handle(map)); |
382 } else if (code->ic_state() == POLYMORPHIC) { | 439 } else if (obj->ic_state() == POLYMORPHIC) { |
383 code->FindAllMaps(&maps); | 440 obj->FindAllMaps(&maps); |
384 } else { | 441 } else { |
385 return; | 442 return; |
386 } | 443 } |
387 types->Reserve(maps.length(), zone()); | 444 types->Reserve(maps.length(), zone()); |
388 for (int i = 0; i < maps.length(); i++) { | 445 for (int i = 0; i < maps.length(); i++) { |
389 Handle<Map> map(maps.at(i)); | 446 Handle<Map> map(maps.at(i)); |
390 if (!CanRetainOtherContext(*map, *native_context_)) { | 447 if (!CanRetainOtherContext(*map, *native_context_)) { |
391 types->AddMapIfMissing(map, zone()); | 448 types->AddMapIfMissing(map, zone()); |
392 } | 449 } |
393 } | 450 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
477 UnseededNumberDictionary::kNotFound); | 534 UnseededNumberDictionary::kNotFound); |
478 // Dictionary has been allocated with sufficient size for all elements. | 535 // Dictionary has been allocated with sufficient size for all elements. |
479 DisallowHeapAllocation no_need_to_resize_dictionary; | 536 DisallowHeapAllocation no_need_to_resize_dictionary; |
480 HandleScope scope(isolate()); | 537 HandleScope scope(isolate()); |
481 USE(UnseededNumberDictionary::AtNumberPut( | 538 USE(UnseededNumberDictionary::AtNumberPut( |
482 dictionary_, IdToKey(ast_id), handle(target, isolate()))); | 539 dictionary_, IdToKey(ast_id), handle(target, isolate()))); |
483 } | 540 } |
484 | 541 |
485 | 542 |
486 } } // namespace v8::internal | 543 } } // namespace v8::internal |
OLD | NEW |