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