OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 return false; | 133 return false; |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { | 137 bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { |
138 Handle<Object> value = GetInfo(expr->id()); | 138 Handle<Object> value = GetInfo(expr->id()); |
139 return value->IsMap() || value->IsSmi() || value->IsJSFunction(); | 139 return value->IsMap() || value->IsSmi() || value->IsJSFunction(); |
140 } | 140 } |
141 | 141 |
142 | 142 |
143 bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) { | |
144 Handle<Object> value = GetInfo(expr->id()); | |
145 return value->IsJSFunction(); | |
146 } | |
147 | |
148 | |
143 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { | 149 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { |
144 ASSERT(LoadIsMonomorphicNormal(expr)); | 150 ASSERT(LoadIsMonomorphicNormal(expr)); |
145 Handle<Object> map_or_code = GetInfo(expr->id()); | 151 Handle<Object> map_or_code = GetInfo(expr->id()); |
146 if (map_or_code->IsCode()) { | 152 if (map_or_code->IsCode()) { |
147 Handle<Code> code = Handle<Code>::cast(map_or_code); | 153 Handle<Code> code = Handle<Code>::cast(map_or_code); |
148 Map* first_map = code->FindFirstMap(); | 154 Map* first_map = code->FindFirstMap(); |
149 ASSERT(first_map != NULL); | 155 ASSERT(first_map != NULL); |
150 return CanRetainOtherContext(first_map, *global_context_) | 156 return CanRetainOtherContext(first_map, *global_context_) |
151 ? Handle<Map>::null() | 157 ? Handle<Map>::null() |
152 : Handle<Map>(first_map); | 158 : Handle<Map>(first_map); |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 // themselves are not GC-safe, so we first get all infos, then we create the | 540 // themselves are not GC-safe, so we first get all infos, then we create the |
535 // dictionary (possibly triggering GC), and finally we relocate the collected | 541 // dictionary (possibly triggering GC), and finally we relocate the collected |
536 // infos before we process them. | 542 // infos before we process them. |
537 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { | 543 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { |
538 AssertNoAllocation no_allocation; | 544 AssertNoAllocation no_allocation; |
539 ZoneList<RelocInfo> infos(16); | 545 ZoneList<RelocInfo> infos(16); |
540 HandleScope scope; | 546 HandleScope scope; |
541 GetRelocInfos(code, &infos); | 547 GetRelocInfos(code, &infos); |
542 CreateDictionary(code, &infos); | 548 CreateDictionary(code, &infos); |
543 ProcessRelocInfos(&infos); | 549 ProcessRelocInfos(&infos); |
550 ProcessTypeFeedbackCells(code); | |
Erik Corry
2012/01/30 15:01:11
This call uses number dictionaries on the heap, an
Vyacheslav Egorov (Chromium)
2012/01/30 15:10:03
Good catch! Yeah, CreateDictionary should add leng
Michael Starzinger
2012/01/30 15:22:58
Nice catch! Fix: https://chromiumcodereview.appspo
| |
544 // Allocate handle in the parent scope. | 551 // Allocate handle in the parent scope. |
545 dictionary_ = scope.CloseAndEscape(dictionary_); | 552 dictionary_ = scope.CloseAndEscape(dictionary_); |
546 } | 553 } |
547 | 554 |
548 | 555 |
549 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code, | 556 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code, |
550 ZoneList<RelocInfo>* infos) { | 557 ZoneList<RelocInfo>* infos) { |
551 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); | 558 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); |
552 for (RelocIterator it(*code, mask); !it.done(); it.next()) { | 559 for (RelocIterator it(*code, mask); !it.done(); it.next()) { |
553 infos->Add(*it.rinfo()); | 560 infos->Add(*it.rinfo()); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 } | 619 } |
613 break; | 620 break; |
614 | 621 |
615 case Code::UNARY_OP_IC: | 622 case Code::UNARY_OP_IC: |
616 case Code::BINARY_OP_IC: | 623 case Code::BINARY_OP_IC: |
617 case Code::COMPARE_IC: | 624 case Code::COMPARE_IC: |
618 case Code::TO_BOOLEAN_IC: | 625 case Code::TO_BOOLEAN_IC: |
619 SetInfo(ast_id, target); | 626 SetInfo(ast_id, target); |
620 break; | 627 break; |
621 | 628 |
622 case Code::STUB: | |
623 if (target->major_key() == CodeStub::CallFunction && | |
624 target->has_function_cache()) { | |
625 Object* value = CallFunctionStub::GetCachedValue(reloc_entry.pc()); | |
626 if (value->IsJSFunction() && | |
627 !CanRetainOtherContext(JSFunction::cast(value), | |
628 *global_context_)) { | |
629 SetInfo(ast_id, value); | |
630 } | |
631 } | |
632 break; | |
633 | |
634 default: | 629 default: |
635 break; | 630 break; |
636 } | 631 } |
637 } | 632 } |
638 } | 633 } |
639 | 634 |
640 | 635 |
636 void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) { | |
637 Handle<TypeFeedbackCells> cache(code->type_feedback_cells()); | |
638 for (int i = 0; i < cache->CellCount(); i++) { | |
639 unsigned ast_id = cache->AstId(i)->value(); | |
640 Object* value = cache->Cell(i)->value(); | |
641 if (value->IsJSFunction() && | |
642 !CanRetainOtherContext(JSFunction::cast(value), | |
643 *global_context_)) { | |
644 SetInfo(ast_id, value); | |
645 } | |
646 } | |
647 } | |
648 | |
649 | |
641 void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) { | 650 void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) { |
642 ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound); | 651 ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound); |
643 MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target); | 652 MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target); |
644 USE(maybe_result); | 653 USE(maybe_result); |
645 #ifdef DEBUG | 654 #ifdef DEBUG |
646 Object* result = NULL; | 655 Object* result = NULL; |
647 // Dictionary has been allocated with sufficient size for all elements. | 656 // Dictionary has been allocated with sufficient size for all elements. |
648 ASSERT(maybe_result->ToObject(&result)); | 657 ASSERT(maybe_result->ToObject(&result)); |
649 ASSERT(*dictionary_ == result); | 658 ASSERT(*dictionary_ == result); |
650 #endif | 659 #endif |
651 } | 660 } |
652 | 661 |
653 } } // namespace v8::internal | 662 } } // namespace v8::internal |
OLD | NEW |