Chromium Code Reviews| 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 |