OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 info = TypeInfo::String(); | 54 info = TypeInfo::String(); |
55 } else { | 55 } else { |
56 info = TypeInfo::Unknown(); | 56 info = TypeInfo::Unknown(); |
57 } | 57 } |
58 return info; | 58 return info; |
59 } | 59 } |
60 | 60 |
61 | 61 |
62 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, | 62 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, |
63 Handle<Context> global_context, | 63 Handle<Context> global_context, |
64 Isolate* isolate) { | 64 Isolate* isolate, |
| 65 Zone* zone) { |
65 global_context_ = global_context; | 66 global_context_ = global_context; |
66 isolate_ = isolate; | 67 isolate_ = isolate; |
| 68 zone_ = zone; |
67 BuildDictionary(code); | 69 BuildDictionary(code); |
68 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue); | 70 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue); |
69 } | 71 } |
70 | 72 |
71 | 73 |
72 Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) { | 74 Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) { |
73 int entry = dictionary_->FindEntry(ast_id); | 75 int entry = dictionary_->FindEntry(ast_id); |
74 return entry != UnseededNumberDictionary::kNotFound | 76 return entry != UnseededNumberDictionary::kNotFound |
75 ? Handle<Object>(dictionary_->ValueAt(entry)) | 77 ? Handle<Object>(dictionary_->ValueAt(entry)) |
76 : Handle<Object>::cast(isolate_->factory()->undefined_value()); | 78 : Handle<Object>::cast(isolate_->factory()->undefined_value()); |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 SmallMapList* types) { | 496 SmallMapList* types) { |
495 Handle<Object> object = GetInfo(ast_id); | 497 Handle<Object> object = GetInfo(ast_id); |
496 if (object->IsUndefined() || object->IsSmi()) return; | 498 if (object->IsUndefined() || object->IsSmi()) return; |
497 | 499 |
498 if (*object == | 500 if (*object == |
499 isolate_->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) { | 501 isolate_->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) { |
500 // TODO(fschneider): We could collect the maps and signal that | 502 // TODO(fschneider): We could collect the maps and signal that |
501 // we need a generic store (or load) here. | 503 // we need a generic store (or load) here. |
502 ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC); | 504 ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC); |
503 } else if (object->IsMap()) { | 505 } else if (object->IsMap()) { |
504 types->Add(Handle<Map>::cast(object)); | 506 types->Add(Handle<Map>::cast(object), zone()); |
505 } else if (FLAG_collect_megamorphic_maps_from_stub_cache && | 507 } else if (FLAG_collect_megamorphic_maps_from_stub_cache && |
506 Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) { | 508 Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) { |
507 types->Reserve(4); | 509 types->Reserve(4, zone()); |
508 ASSERT(object->IsCode()); | 510 ASSERT(object->IsCode()); |
509 isolate_->stub_cache()->CollectMatchingMaps(types, | 511 isolate_->stub_cache()->CollectMatchingMaps(types, |
510 *name, | 512 *name, |
511 flags, | 513 flags, |
512 global_context_); | 514 global_context_); |
513 } | 515 } |
514 } | 516 } |
515 | 517 |
516 | 518 |
517 // Check if a map originates from a given global context. We use this | 519 // Check if a map originates from a given global context. We use this |
(...skipping 23 matching lines...) Expand all Loading... |
541 } | 543 } |
542 | 544 |
543 | 545 |
544 bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function, | 546 bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function, |
545 Context* global_context) { | 547 Context* global_context) { |
546 return function->context()->global() != global_context->global() | 548 return function->context()->global() != global_context->global() |
547 && function->context()->global() != global_context->builtins(); | 549 && function->context()->global() != global_context->builtins(); |
548 } | 550 } |
549 | 551 |
550 | 552 |
551 static void AddMapIfMissing(Handle<Map> map, SmallMapList* list) { | 553 static void AddMapIfMissing(Handle<Map> map, SmallMapList* list, |
| 554 Zone* zone) { |
552 for (int i = 0; i < list->length(); ++i) { | 555 for (int i = 0; i < list->length(); ++i) { |
553 if (list->at(i).is_identical_to(map)) return; | 556 if (list->at(i).is_identical_to(map)) return; |
554 } | 557 } |
555 list->Add(map); | 558 list->Add(map, zone); |
556 } | 559 } |
557 | 560 |
558 | 561 |
559 void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id, | 562 void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id, |
560 SmallMapList* types) { | 563 SmallMapList* types) { |
561 Handle<Object> object = GetInfo(ast_id); | 564 Handle<Object> object = GetInfo(ast_id); |
562 if (!object->IsCode()) return; | 565 if (!object->IsCode()) return; |
563 Handle<Code> code = Handle<Code>::cast(object); | 566 Handle<Code> code = Handle<Code>::cast(object); |
564 if (code->kind() == Code::KEYED_LOAD_IC || | 567 if (code->kind() == Code::KEYED_LOAD_IC || |
565 code->kind() == Code::KEYED_STORE_IC) { | 568 code->kind() == Code::KEYED_STORE_IC) { |
566 AssertNoAllocation no_allocation; | 569 AssertNoAllocation no_allocation; |
567 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 570 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
568 for (RelocIterator it(*code, mask); !it.done(); it.next()) { | 571 for (RelocIterator it(*code, mask); !it.done(); it.next()) { |
569 RelocInfo* info = it.rinfo(); | 572 RelocInfo* info = it.rinfo(); |
570 Object* object = info->target_object(); | 573 Object* object = info->target_object(); |
571 if (object->IsMap()) { | 574 if (object->IsMap()) { |
572 Map* map = Map::cast(object); | 575 Map* map = Map::cast(object); |
573 if (!CanRetainOtherContext(map, *global_context_)) { | 576 if (!CanRetainOtherContext(map, *global_context_)) { |
574 AddMapIfMissing(Handle<Map>(map), types); | 577 AddMapIfMissing(Handle<Map>(map), types, zone()); |
575 } | 578 } |
576 } | 579 } |
577 } | 580 } |
578 } | 581 } |
579 } | 582 } |
580 | 583 |
581 | 584 |
582 byte TypeFeedbackOracle::ToBooleanTypes(unsigned ast_id) { | 585 byte TypeFeedbackOracle::ToBooleanTypes(unsigned ast_id) { |
583 Handle<Object> object = GetInfo(ast_id); | 586 Handle<Object> object = GetInfo(ast_id); |
584 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0; | 587 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0; |
585 } | 588 } |
586 | 589 |
587 | 590 |
588 // Things are a bit tricky here: The iterator for the RelocInfos and the infos | 591 // Things are a bit tricky here: The iterator for the RelocInfos and the infos |
589 // themselves are not GC-safe, so we first get all infos, then we create the | 592 // themselves are not GC-safe, so we first get all infos, then we create the |
590 // dictionary (possibly triggering GC), and finally we relocate the collected | 593 // dictionary (possibly triggering GC), and finally we relocate the collected |
591 // infos before we process them. | 594 // infos before we process them. |
592 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { | 595 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { |
593 AssertNoAllocation no_allocation; | 596 AssertNoAllocation no_allocation; |
594 ZoneList<RelocInfo> infos(16); | 597 ZoneList<RelocInfo> infos(16, zone()); |
595 HandleScope scope; | 598 HandleScope scope; |
596 GetRelocInfos(code, &infos); | 599 GetRelocInfos(code, &infos); |
597 CreateDictionary(code, &infos); | 600 CreateDictionary(code, &infos); |
598 ProcessRelocInfos(&infos); | 601 ProcessRelocInfos(&infos); |
599 ProcessTypeFeedbackCells(code); | 602 ProcessTypeFeedbackCells(code); |
600 // Allocate handle in the parent scope. | 603 // Allocate handle in the parent scope. |
601 dictionary_ = scope.CloseAndEscape(dictionary_); | 604 dictionary_ = scope.CloseAndEscape(dictionary_); |
602 } | 605 } |
603 | 606 |
604 | 607 |
605 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code, | 608 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code, |
606 ZoneList<RelocInfo>* infos) { | 609 ZoneList<RelocInfo>* infos) { |
607 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); | 610 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); |
608 for (RelocIterator it(*code, mask); !it.done(); it.next()) { | 611 for (RelocIterator it(*code, mask); !it.done(); it.next()) { |
609 infos->Add(*it.rinfo()); | 612 infos->Add(*it.rinfo(), zone()); |
610 } | 613 } |
611 } | 614 } |
612 | 615 |
613 | 616 |
614 void TypeFeedbackOracle::CreateDictionary(Handle<Code> code, | 617 void TypeFeedbackOracle::CreateDictionary(Handle<Code> code, |
615 ZoneList<RelocInfo>* infos) { | 618 ZoneList<RelocInfo>* infos) { |
616 DisableAssertNoAllocation allocation_allowed; | 619 DisableAssertNoAllocation allocation_allowed; |
617 int cell_count = code->type_feedback_info()->IsTypeFeedbackInfo() | 620 int cell_count = code->type_feedback_info()->IsTypeFeedbackInfo() |
618 ? TypeFeedbackInfo::cast(code->type_feedback_info())-> | 621 ? TypeFeedbackInfo::cast(code->type_feedback_info())-> |
619 type_feedback_cells()->CellCount() | 622 type_feedback_cells()->CellCount() |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 USE(maybe_result); | 714 USE(maybe_result); |
712 #ifdef DEBUG | 715 #ifdef DEBUG |
713 Object* result = NULL; | 716 Object* result = NULL; |
714 // Dictionary has been allocated with sufficient size for all elements. | 717 // Dictionary has been allocated with sufficient size for all elements. |
715 ASSERT(maybe_result->ToObject(&result)); | 718 ASSERT(maybe_result->ToObject(&result)); |
716 ASSERT(*dictionary_ == result); | 719 ASSERT(*dictionary_ == result); |
717 #endif | 720 #endif |
718 } | 721 } |
719 | 722 |
720 } } // namespace v8::internal | 723 } } // namespace v8::internal |
OLD | NEW |