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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 new_space_high_promotion_mode_active_(false), | 120 new_space_high_promotion_mode_active_(false), |
121 old_gen_promotion_limit_(kMinimumPromotionLimit), | 121 old_gen_promotion_limit_(kMinimumPromotionLimit), |
122 old_gen_allocation_limit_(kMinimumAllocationLimit), | 122 old_gen_allocation_limit_(kMinimumAllocationLimit), |
123 old_gen_limit_factor_(1), | 123 old_gen_limit_factor_(1), |
124 size_of_old_gen_at_last_old_space_gc_(0), | 124 size_of_old_gen_at_last_old_space_gc_(0), |
125 external_allocation_limit_(0), | 125 external_allocation_limit_(0), |
126 amount_of_external_allocated_memory_(0), | 126 amount_of_external_allocated_memory_(0), |
127 amount_of_external_allocated_memory_at_last_global_gc_(0), | 127 amount_of_external_allocated_memory_at_last_global_gc_(0), |
128 old_gen_exhausted_(false), | 128 old_gen_exhausted_(false), |
129 store_buffer_rebuilder_(store_buffer()), | 129 store_buffer_rebuilder_(store_buffer()), |
130 hidden_symbol_(NULL), | 130 hidden_string_(NULL), |
131 global_gc_prologue_callback_(NULL), | 131 global_gc_prologue_callback_(NULL), |
132 global_gc_epilogue_callback_(NULL), | 132 global_gc_epilogue_callback_(NULL), |
133 gc_safe_size_of_old_object_(NULL), | 133 gc_safe_size_of_old_object_(NULL), |
134 total_regexp_code_generated_(0), | 134 total_regexp_code_generated_(0), |
135 tracer_(NULL), | 135 tracer_(NULL), |
136 young_survivors_after_last_gc_(0), | 136 young_survivors_after_last_gc_(0), |
137 high_survival_rate_period_length_(0), | 137 high_survival_rate_period_length_(0), |
138 low_survival_rate_period_length_(0), | 138 low_survival_rate_period_length_(0), |
139 survival_rate_(0), | 139 survival_rate_(0), |
140 previous_survival_rate_trend_(Heap::STABLE), | 140 previous_survival_rate_trend_(Heap::STABLE), |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 allow_allocation(true); | 485 allow_allocation(true); |
486 if (FLAG_print_global_handles) isolate_->global_handles()->Print(); | 486 if (FLAG_print_global_handles) isolate_->global_handles()->Print(); |
487 if (FLAG_print_handles) PrintHandles(); | 487 if (FLAG_print_handles) PrintHandles(); |
488 if (FLAG_gc_verbose) Print(); | 488 if (FLAG_gc_verbose) Print(); |
489 if (FLAG_code_stats) ReportCodeStatistics("After GC"); | 489 if (FLAG_code_stats) ReportCodeStatistics("After GC"); |
490 #endif | 490 #endif |
491 | 491 |
492 isolate_->counters()->alive_after_last_gc()->Set( | 492 isolate_->counters()->alive_after_last_gc()->Set( |
493 static_cast<int>(SizeOfObjects())); | 493 static_cast<int>(SizeOfObjects())); |
494 | 494 |
495 isolate_->counters()->symbol_table_capacity()->Set( | 495 isolate_->counters()->string_table_capacity()->Set( |
496 symbol_table()->Capacity()); | 496 string_table()->Capacity()); |
497 isolate_->counters()->number_of_symbols()->Set( | 497 isolate_->counters()->number_of_symbols()->Set( |
498 symbol_table()->NumberOfElements()); | 498 string_table()->NumberOfElements()); |
499 | 499 |
500 if (CommittedMemory() > 0) { | 500 if (CommittedMemory() > 0) { |
501 isolate_->counters()->external_fragmentation_total()->AddSample( | 501 isolate_->counters()->external_fragmentation_total()->AddSample( |
502 static_cast<int>(100 - (SizeOfObjects() * 100.0) / CommittedMemory())); | 502 static_cast<int>(100 - (SizeOfObjects() * 100.0) / CommittedMemory())); |
503 | 503 |
504 isolate_->counters()->heap_fraction_map_space()->AddSample( | 504 isolate_->counters()->heap_fraction_map_space()->AddSample( |
505 static_cast<int>( | 505 static_cast<int>( |
506 (map_space()->CommittedMemory() * 100.0) / CommittedMemory())); | 506 (map_space()->CommittedMemory() * 100.0) / CommittedMemory())); |
507 isolate_->counters()->heap_fraction_cell_space()->AddSample( | 507 isolate_->counters()->heap_fraction_cell_space()->AddSample( |
508 static_cast<int>( | 508 static_cast<int>( |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 if (InNewSpace(dst_objects[i])) { | 698 if (InNewSpace(dst_objects[i])) { |
699 RecordWrite(array->address(), array->OffsetOfElementAt(dst_index + i)); | 699 RecordWrite(array->address(), array->OffsetOfElementAt(dst_index + i)); |
700 } | 700 } |
701 } | 701 } |
702 } | 702 } |
703 incremental_marking()->RecordWrites(array); | 703 incremental_marking()->RecordWrites(array); |
704 } | 704 } |
705 | 705 |
706 | 706 |
707 #ifdef VERIFY_HEAP | 707 #ifdef VERIFY_HEAP |
708 // Helper class for verifying the symbol table. | 708 // Helper class for verifying the string table. |
709 class SymbolTableVerifier : public ObjectVisitor { | 709 class StringTableVerifier : public ObjectVisitor { |
710 public: | 710 public: |
711 void VisitPointers(Object** start, Object** end) { | 711 void VisitPointers(Object** start, Object** end) { |
712 // Visit all HeapObject pointers in [start, end). | 712 // Visit all HeapObject pointers in [start, end). |
713 for (Object** p = start; p < end; p++) { | 713 for (Object** p = start; p < end; p++) { |
714 if ((*p)->IsHeapObject()) { | 714 if ((*p)->IsHeapObject()) { |
715 // Check that the symbol is actually a symbol. | 715 // Check that the string is actually internalized. |
716 CHECK((*p)->IsTheHole() || (*p)->IsUndefined() || (*p)->IsSymbol()); | 716 CHECK((*p)->IsTheHole() || (*p)->IsUndefined() || |
| 717 (*p)->IsInternalizedString()); |
717 } | 718 } |
718 } | 719 } |
719 } | 720 } |
720 }; | 721 }; |
721 | 722 |
722 | 723 |
723 static void VerifySymbolTable() { | 724 static void VerifyStringTable() { |
724 SymbolTableVerifier verifier; | 725 StringTableVerifier verifier; |
725 HEAP->symbol_table()->IterateElements(&verifier); | 726 HEAP->string_table()->IterateElements(&verifier); |
726 } | 727 } |
727 #endif // VERIFY_HEAP | 728 #endif // VERIFY_HEAP |
728 | 729 |
729 | 730 |
730 static bool AbortIncrementalMarkingAndCollectGarbage( | 731 static bool AbortIncrementalMarkingAndCollectGarbage( |
731 Heap* heap, | 732 Heap* heap, |
732 AllocationSpace space, | 733 AllocationSpace space, |
733 const char* gc_reason = NULL) { | 734 const char* gc_reason = NULL) { |
734 heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask); | 735 heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask); |
735 bool result = heap->CollectGarbage(space, gc_reason); | 736 bool result = heap->CollectGarbage(space, gc_reason); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 bool Heap::PerformGarbageCollection(GarbageCollector collector, | 877 bool Heap::PerformGarbageCollection(GarbageCollector collector, |
877 GCTracer* tracer) { | 878 GCTracer* tracer) { |
878 bool next_gc_likely_to_collect_more = false; | 879 bool next_gc_likely_to_collect_more = false; |
879 | 880 |
880 if (collector != SCAVENGER) { | 881 if (collector != SCAVENGER) { |
881 PROFILE(isolate_, CodeMovingGCEvent()); | 882 PROFILE(isolate_, CodeMovingGCEvent()); |
882 } | 883 } |
883 | 884 |
884 #ifdef VERIFY_HEAP | 885 #ifdef VERIFY_HEAP |
885 if (FLAG_verify_heap) { | 886 if (FLAG_verify_heap) { |
886 VerifySymbolTable(); | 887 VerifyStringTable(); |
887 } | 888 } |
888 #endif | 889 #endif |
889 | 890 |
890 GCType gc_type = | 891 GCType gc_type = |
891 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; | 892 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; |
892 | 893 |
893 { | 894 { |
894 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 895 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
895 VMState state(isolate_, EXTERNAL); | 896 VMState state(isolate_, EXTERNAL); |
896 CallGCPrologueCallbacks(gc_type); | 897 CallGCPrologueCallbacks(gc_type); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 } | 1002 } |
1002 | 1003 |
1003 { | 1004 { |
1004 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 1005 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
1005 VMState state(isolate_, EXTERNAL); | 1006 VMState state(isolate_, EXTERNAL); |
1006 CallGCEpilogueCallbacks(gc_type); | 1007 CallGCEpilogueCallbacks(gc_type); |
1007 } | 1008 } |
1008 | 1009 |
1009 #ifdef VERIFY_HEAP | 1010 #ifdef VERIFY_HEAP |
1010 if (FLAG_verify_heap) { | 1011 if (FLAG_verify_heap) { |
1011 VerifySymbolTable(); | 1012 VerifyStringTable(); |
1012 } | 1013 } |
1013 #endif | 1014 #endif |
1014 | 1015 |
1015 return next_gc_likely_to_collect_more; | 1016 return next_gc_likely_to_collect_more; |
1016 } | 1017 } |
1017 | 1018 |
1018 | 1019 |
1019 void Heap::CallGCPrologueCallbacks(GCType gc_type) { | 1020 void Heap::CallGCPrologueCallbacks(GCType gc_type) { |
1020 if (gc_type == kGCTypeMarkSweepCompact && global_gc_prologue_callback_) { | 1021 if (gc_type == kGCTypeMarkSweepCompact && global_gc_prologue_callback_) { |
1021 global_gc_prologue_callback_(); | 1022 global_gc_prologue_callback_(); |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1618 } | 1619 } |
1619 | 1620 |
1620 // Update the head of the list of contexts. | 1621 // Update the head of the list of contexts. |
1621 native_contexts_list_ = head; | 1622 native_contexts_list_ = head; |
1622 } | 1623 } |
1623 | 1624 |
1624 | 1625 |
1625 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { | 1626 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { |
1626 AssertNoAllocation no_allocation; | 1627 AssertNoAllocation no_allocation; |
1627 | 1628 |
1628 // Both the external string table and the symbol table may contain | 1629 // Both the external string table and the string table may contain |
1629 // external strings, but neither lists them exhaustively, nor is the | 1630 // external strings, but neither lists them exhaustively, nor is the |
1630 // intersection set empty. Therefore we iterate over the external string | 1631 // intersection set empty. Therefore we iterate over the external string |
1631 // table first, ignoring symbols, and then over the symbol table. | 1632 // table first, ignoring internalized strings, and then over the |
| 1633 // internalized string table. |
1632 | 1634 |
1633 class ExternalStringTableVisitorAdapter : public ObjectVisitor { | 1635 class ExternalStringTableVisitorAdapter : public ObjectVisitor { |
1634 public: | 1636 public: |
1635 explicit ExternalStringTableVisitorAdapter( | 1637 explicit ExternalStringTableVisitorAdapter( |
1636 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {} | 1638 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {} |
1637 virtual void VisitPointers(Object** start, Object** end) { | 1639 virtual void VisitPointers(Object** start, Object** end) { |
1638 for (Object** p = start; p < end; p++) { | 1640 for (Object** p = start; p < end; p++) { |
1639 // Visit non-symbol external strings, | 1641 // Visit non-internalized external strings, |
1640 // since symbols are listed in the symbol table. | 1642 // since internalized strings are listed in the string table. |
1641 if (!(*p)->IsSymbol()) { | 1643 if (!(*p)->IsInternalizedString()) { |
1642 ASSERT((*p)->IsExternalString()); | 1644 ASSERT((*p)->IsExternalString()); |
1643 visitor_->VisitExternalString(Utils::ToLocal( | 1645 visitor_->VisitExternalString(Utils::ToLocal( |
1644 Handle<String>(String::cast(*p)))); | 1646 Handle<String>(String::cast(*p)))); |
1645 } | 1647 } |
1646 } | 1648 } |
1647 } | 1649 } |
1648 private: | 1650 private: |
1649 v8::ExternalResourceVisitor* visitor_; | 1651 v8::ExternalResourceVisitor* visitor_; |
1650 } external_string_table_visitor(visitor); | 1652 } external_string_table_visitor(visitor); |
1651 | 1653 |
1652 external_string_table_.Iterate(&external_string_table_visitor); | 1654 external_string_table_.Iterate(&external_string_table_visitor); |
1653 | 1655 |
1654 class SymbolTableVisitorAdapter : public ObjectVisitor { | 1656 class StringTableVisitorAdapter : public ObjectVisitor { |
1655 public: | 1657 public: |
1656 explicit SymbolTableVisitorAdapter( | 1658 explicit StringTableVisitorAdapter( |
1657 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {} | 1659 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {} |
1658 virtual void VisitPointers(Object** start, Object** end) { | 1660 virtual void VisitPointers(Object** start, Object** end) { |
1659 for (Object** p = start; p < end; p++) { | 1661 for (Object** p = start; p < end; p++) { |
1660 if ((*p)->IsExternalString()) { | 1662 if ((*p)->IsExternalString()) { |
1661 ASSERT((*p)->IsSymbol()); | 1663 ASSERT((*p)->IsInternalizedString()); |
1662 visitor_->VisitExternalString(Utils::ToLocal( | 1664 visitor_->VisitExternalString(Utils::ToLocal( |
1663 Handle<String>(String::cast(*p)))); | 1665 Handle<String>(String::cast(*p)))); |
1664 } | 1666 } |
1665 } | 1667 } |
1666 } | 1668 } |
1667 private: | 1669 private: |
1668 v8::ExternalResourceVisitor* visitor_; | 1670 v8::ExternalResourceVisitor* visitor_; |
1669 } symbol_table_visitor(visitor); | 1671 } string_table_visitor(visitor); |
1670 | 1672 |
1671 symbol_table()->IterateElements(&symbol_table_visitor); | 1673 string_table()->IterateElements(&string_table_visitor); |
1672 } | 1674 } |
1673 | 1675 |
1674 | 1676 |
1675 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> { | 1677 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> { |
1676 public: | 1678 public: |
1677 static inline void VisitPointer(Heap* heap, Object** p) { | 1679 static inline void VisitPointer(Heap* heap, Object** p) { |
1678 Object* object = *p; | 1680 Object* object = *p; |
1679 if (!heap->InNewSpace(object)) return; | 1681 if (!heap->InNewSpace(object)) return; |
1680 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), | 1682 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), |
1681 reinterpret_cast<HeapObject*>(object)); | 1683 reinterpret_cast<HeapObject*>(object)); |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2271 | 2273 |
2272 | 2274 |
2273 const Heap::StringTypeTable Heap::string_type_table[] = { | 2275 const Heap::StringTypeTable Heap::string_type_table[] = { |
2274 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ | 2276 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ |
2275 {type, size, k##camel_name##MapRootIndex}, | 2277 {type, size, k##camel_name##MapRootIndex}, |
2276 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) | 2278 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) |
2277 #undef STRING_TYPE_ELEMENT | 2279 #undef STRING_TYPE_ELEMENT |
2278 }; | 2280 }; |
2279 | 2281 |
2280 | 2282 |
2281 const Heap::ConstantSymbolTable Heap::constant_symbol_table[] = { | 2283 const Heap::ConstantStringTable Heap::constant_string_table[] = { |
2282 #define CONSTANT_SYMBOL_ELEMENT(name, contents) \ | 2284 #define CONSTANT_STRING_ELEMENT(name, contents) \ |
2283 {contents, k##name##RootIndex}, | 2285 {contents, k##name##RootIndex}, |
2284 SYMBOL_LIST(CONSTANT_SYMBOL_ELEMENT) | 2286 INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT) |
2285 #undef CONSTANT_SYMBOL_ELEMENT | 2287 #undef CONSTANT_STRING_ELEMENT |
2286 }; | 2288 }; |
2287 | 2289 |
2288 | 2290 |
2289 const Heap::StructTable Heap::struct_table[] = { | 2291 const Heap::StructTable Heap::struct_table[] = { |
2290 #define STRUCT_TABLE_ELEMENT(NAME, Name, name) \ | 2292 #define STRUCT_TABLE_ELEMENT(NAME, Name, name) \ |
2291 { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex }, | 2293 { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex }, |
2292 STRUCT_LIST(STRUCT_TABLE_ELEMENT) | 2294 STRUCT_LIST(STRUCT_TABLE_ELEMENT) |
2293 #undef STRUCT_TABLE_ELEMENT | 2295 #undef STRUCT_TABLE_ELEMENT |
2294 }; | 2296 }; |
2295 | 2297 |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2738 if (!maybe_obj->ToObject(&obj)) return false; | 2740 if (!maybe_obj->ToObject(&obj)) return false; |
2739 } | 2741 } |
2740 set_nan_value(HeapNumber::cast(obj)); | 2742 set_nan_value(HeapNumber::cast(obj)); |
2741 | 2743 |
2742 { MaybeObject* maybe_obj = AllocateHeapNumber(V8_INFINITY, TENURED); | 2744 { MaybeObject* maybe_obj = AllocateHeapNumber(V8_INFINITY, TENURED); |
2743 if (!maybe_obj->ToObject(&obj)) return false; | 2745 if (!maybe_obj->ToObject(&obj)) return false; |
2744 } | 2746 } |
2745 set_infinity_value(HeapNumber::cast(obj)); | 2747 set_infinity_value(HeapNumber::cast(obj)); |
2746 | 2748 |
2747 // The hole has not been created yet, but we want to put something | 2749 // The hole has not been created yet, but we want to put something |
2748 // predictable in the gaps in the symbol table, so lets make that Smi zero. | 2750 // predictable in the gaps in the string table, so lets make that Smi zero. |
2749 set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0))); | 2751 set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0))); |
2750 | 2752 |
2751 // Allocate initial symbol table. | 2753 // Allocate initial string table. |
2752 { MaybeObject* maybe_obj = SymbolTable::Allocate(kInitialSymbolTableSize); | 2754 { MaybeObject* maybe_obj = StringTable::Allocate(kInitialStringTableSize); |
2753 if (!maybe_obj->ToObject(&obj)) return false; | 2755 if (!maybe_obj->ToObject(&obj)) return false; |
2754 } | 2756 } |
2755 // Don't use set_symbol_table() due to asserts. | 2757 // Don't use set_string_table() due to asserts. |
2756 roots_[kSymbolTableRootIndex] = obj; | 2758 roots_[kStringTableRootIndex] = obj; |
2757 | 2759 |
2758 // Finish initializing oddballs after creating symboltable. | 2760 // Finish initializing oddballs after creating the string table. |
2759 { MaybeObject* maybe_obj = | 2761 { MaybeObject* maybe_obj = |
2760 undefined_value()->Initialize("undefined", | 2762 undefined_value()->Initialize("undefined", |
2761 nan_value(), | 2763 nan_value(), |
2762 Oddball::kUndefined); | 2764 Oddball::kUndefined); |
2763 if (!maybe_obj->ToObject(&obj)) return false; | 2765 if (!maybe_obj->ToObject(&obj)) return false; |
2764 } | 2766 } |
2765 | 2767 |
2766 // Initialize the null_value. | 2768 // Initialize the null_value. |
2767 { MaybeObject* maybe_obj = | 2769 { MaybeObject* maybe_obj = |
2768 null_value()->Initialize("null", Smi::FromInt(0), Oddball::kNull); | 2770 null_value()->Initialize("null", Smi::FromInt(0), Oddball::kNull); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2804 } | 2806 } |
2805 set_no_interceptor_result_sentinel(obj); | 2807 set_no_interceptor_result_sentinel(obj); |
2806 | 2808 |
2807 { MaybeObject* maybe_obj = CreateOddball("termination_exception", | 2809 { MaybeObject* maybe_obj = CreateOddball("termination_exception", |
2808 Smi::FromInt(-3), | 2810 Smi::FromInt(-3), |
2809 Oddball::kOther); | 2811 Oddball::kOther); |
2810 if (!maybe_obj->ToObject(&obj)) return false; | 2812 if (!maybe_obj->ToObject(&obj)) return false; |
2811 } | 2813 } |
2812 set_termination_exception(obj); | 2814 set_termination_exception(obj); |
2813 | 2815 |
2814 // Allocate the empty string. | 2816 for (unsigned i = 0; i < ARRAY_SIZE(constant_string_table); i++) { |
2815 { MaybeObject* maybe_obj = AllocateRawOneByteString(0, TENURED); | |
2816 if (!maybe_obj->ToObject(&obj)) return false; | |
2817 } | |
2818 set_empty_string(String::cast(obj)); | |
2819 | |
2820 for (unsigned i = 0; i < ARRAY_SIZE(constant_symbol_table); i++) { | |
2821 { MaybeObject* maybe_obj = | 2817 { MaybeObject* maybe_obj = |
2822 LookupUtf8Symbol(constant_symbol_table[i].contents); | 2818 InternalizeUtf8String(constant_string_table[i].contents); |
2823 if (!maybe_obj->ToObject(&obj)) return false; | 2819 if (!maybe_obj->ToObject(&obj)) return false; |
2824 } | 2820 } |
2825 roots_[constant_symbol_table[i].index] = String::cast(obj); | 2821 roots_[constant_string_table[i].index] = String::cast(obj); |
2826 } | 2822 } |
2827 | 2823 |
2828 // Allocate the hidden symbol which is used to identify the hidden properties | 2824 // Allocate the hidden string which is used to identify the hidden properties |
2829 // in JSObjects. The hash code has a special value so that it will not match | 2825 // in JSObjects. The hash code has a special value so that it will not match |
2830 // the empty string when searching for the property. It cannot be part of the | 2826 // the empty string when searching for the property. It cannot be part of the |
2831 // loop above because it needs to be allocated manually with the special | 2827 // loop above because it needs to be allocated manually with the special |
2832 // hash code in place. The hash code for the hidden_symbol is zero to ensure | 2828 // hash code in place. The hash code for the hidden_string is zero to ensure |
2833 // that it will always be at the first entry in property descriptors. | 2829 // that it will always be at the first entry in property descriptors. |
2834 { MaybeObject* maybe_obj = | 2830 { MaybeObject* maybe_obj = AllocateOneByteInternalizedString( |
2835 AllocateOneByteSymbol(OneByteVector("", 0), String::kEmptyStringHash); | 2831 OneByteVector("", 0), String::kEmptyStringHash); |
2836 if (!maybe_obj->ToObject(&obj)) return false; | 2832 if (!maybe_obj->ToObject(&obj)) return false; |
2837 } | 2833 } |
2838 hidden_symbol_ = String::cast(obj); | 2834 hidden_string_ = String::cast(obj); |
2839 | 2835 |
2840 // Allocate the foreign for __proto__. | 2836 // Allocate the foreign for __proto__. |
2841 { MaybeObject* maybe_obj = | 2837 { MaybeObject* maybe_obj = |
2842 AllocateForeign((Address) &Accessors::ObjectPrototype); | 2838 AllocateForeign((Address) &Accessors::ObjectPrototype); |
2843 if (!maybe_obj->ToObject(&obj)) return false; | 2839 if (!maybe_obj->ToObject(&obj)) return false; |
2844 } | 2840 } |
2845 set_prototype_accessors(Foreign::cast(obj)); | 2841 set_prototype_accessors(Foreign::cast(obj)); |
2846 | 2842 |
2847 // Allocate the code_stubs dictionary. The initial size is set to avoid | 2843 // Allocate the code_stubs dictionary. The initial size is set to avoid |
2848 // expanding the dictionary during bootstrapping. | 2844 // expanding the dictionary during bootstrapping. |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2950 kCodeStubsRootIndex, | 2946 kCodeStubsRootIndex, |
2951 kNonMonomorphicCacheRootIndex, | 2947 kNonMonomorphicCacheRootIndex, |
2952 kPolymorphicCodeCacheRootIndex, | 2948 kPolymorphicCodeCacheRootIndex, |
2953 kLastScriptIdRootIndex, | 2949 kLastScriptIdRootIndex, |
2954 kEmptyScriptRootIndex, | 2950 kEmptyScriptRootIndex, |
2955 kRealStackLimitRootIndex, | 2951 kRealStackLimitRootIndex, |
2956 kArgumentsAdaptorDeoptPCOffsetRootIndex, | 2952 kArgumentsAdaptorDeoptPCOffsetRootIndex, |
2957 kConstructStubDeoptPCOffsetRootIndex, | 2953 kConstructStubDeoptPCOffsetRootIndex, |
2958 kGetterStubDeoptPCOffsetRootIndex, | 2954 kGetterStubDeoptPCOffsetRootIndex, |
2959 kSetterStubDeoptPCOffsetRootIndex, | 2955 kSetterStubDeoptPCOffsetRootIndex, |
2960 kSymbolTableRootIndex, | 2956 kStringTableRootIndex, |
2961 }; | 2957 }; |
2962 | 2958 |
2963 for (unsigned int i = 0; i < ARRAY_SIZE(writable_roots); i++) { | 2959 for (unsigned int i = 0; i < ARRAY_SIZE(writable_roots); i++) { |
2964 if (root_index == writable_roots[i]) | 2960 if (root_index == writable_roots[i]) |
2965 return true; | 2961 return true; |
2966 } | 2962 } |
2967 return false; | 2963 return false; |
2968 } | 2964 } |
2969 | 2965 |
2970 | 2966 |
2971 Object* RegExpResultsCache::Lookup(Heap* heap, | 2967 Object* RegExpResultsCache::Lookup(Heap* heap, |
2972 String* key_string, | 2968 String* key_string, |
2973 Object* key_pattern, | 2969 Object* key_pattern, |
2974 ResultsCacheType type) { | 2970 ResultsCacheType type) { |
2975 FixedArray* cache; | 2971 FixedArray* cache; |
2976 if (!key_string->IsSymbol()) return Smi::FromInt(0); | 2972 if (!key_string->IsInternalizedString()) return Smi::FromInt(0); |
2977 if (type == STRING_SPLIT_SUBSTRINGS) { | 2973 if (type == STRING_SPLIT_SUBSTRINGS) { |
2978 ASSERT(key_pattern->IsString()); | 2974 ASSERT(key_pattern->IsString()); |
2979 if (!key_pattern->IsSymbol()) return Smi::FromInt(0); | 2975 if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0); |
2980 cache = heap->string_split_cache(); | 2976 cache = heap->string_split_cache(); |
2981 } else { | 2977 } else { |
2982 ASSERT(type == REGEXP_MULTIPLE_INDICES); | 2978 ASSERT(type == REGEXP_MULTIPLE_INDICES); |
2983 ASSERT(key_pattern->IsFixedArray()); | 2979 ASSERT(key_pattern->IsFixedArray()); |
2984 cache = heap->regexp_multiple_cache(); | 2980 cache = heap->regexp_multiple_cache(); |
2985 } | 2981 } |
2986 | 2982 |
2987 uint32_t hash = key_string->Hash(); | 2983 uint32_t hash = key_string->Hash(); |
2988 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & | 2984 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & |
2989 ~(kArrayEntriesPerCacheEntry - 1)); | 2985 ~(kArrayEntriesPerCacheEntry - 1)); |
(...skipping 10 matching lines...) Expand all Loading... |
3000 return Smi::FromInt(0); | 2996 return Smi::FromInt(0); |
3001 } | 2997 } |
3002 | 2998 |
3003 | 2999 |
3004 void RegExpResultsCache::Enter(Heap* heap, | 3000 void RegExpResultsCache::Enter(Heap* heap, |
3005 String* key_string, | 3001 String* key_string, |
3006 Object* key_pattern, | 3002 Object* key_pattern, |
3007 FixedArray* value_array, | 3003 FixedArray* value_array, |
3008 ResultsCacheType type) { | 3004 ResultsCacheType type) { |
3009 FixedArray* cache; | 3005 FixedArray* cache; |
3010 if (!key_string->IsSymbol()) return; | 3006 if (!key_string->IsInternalizedString()) return; |
3011 if (type == STRING_SPLIT_SUBSTRINGS) { | 3007 if (type == STRING_SPLIT_SUBSTRINGS) { |
3012 ASSERT(key_pattern->IsString()); | 3008 ASSERT(key_pattern->IsString()); |
3013 if (!key_pattern->IsSymbol()) return; | 3009 if (!key_pattern->IsInternalizedString()) return; |
3014 cache = heap->string_split_cache(); | 3010 cache = heap->string_split_cache(); |
3015 } else { | 3011 } else { |
3016 ASSERT(type == REGEXP_MULTIPLE_INDICES); | 3012 ASSERT(type == REGEXP_MULTIPLE_INDICES); |
3017 ASSERT(key_pattern->IsFixedArray()); | 3013 ASSERT(key_pattern->IsFixedArray()); |
3018 cache = heap->regexp_multiple_cache(); | 3014 cache = heap->regexp_multiple_cache(); |
3019 } | 3015 } |
3020 | 3016 |
3021 uint32_t hash = key_string->Hash(); | 3017 uint32_t hash = key_string->Hash(); |
3022 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & | 3018 uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & |
3023 ~(kArrayEntriesPerCacheEntry - 1)); | 3019 ~(kArrayEntriesPerCacheEntry - 1)); |
(...skipping 11 matching lines...) Expand all Loading... |
3035 } else { | 3031 } else { |
3036 cache->set(index2 + kStringOffset, Smi::FromInt(0)); | 3032 cache->set(index2 + kStringOffset, Smi::FromInt(0)); |
3037 cache->set(index2 + kPatternOffset, Smi::FromInt(0)); | 3033 cache->set(index2 + kPatternOffset, Smi::FromInt(0)); |
3038 cache->set(index2 + kArrayOffset, Smi::FromInt(0)); | 3034 cache->set(index2 + kArrayOffset, Smi::FromInt(0)); |
3039 cache->set(index + kStringOffset, key_string); | 3035 cache->set(index + kStringOffset, key_string); |
3040 cache->set(index + kPatternOffset, key_pattern); | 3036 cache->set(index + kPatternOffset, key_pattern); |
3041 cache->set(index + kArrayOffset, value_array); | 3037 cache->set(index + kArrayOffset, value_array); |
3042 } | 3038 } |
3043 } | 3039 } |
3044 // If the array is a reasonably short list of substrings, convert it into a | 3040 // If the array is a reasonably short list of substrings, convert it into a |
3045 // list of symbols. | 3041 // list of internalized strings. |
3046 if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { | 3042 if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) { |
3047 for (int i = 0; i < value_array->length(); i++) { | 3043 for (int i = 0; i < value_array->length(); i++) { |
3048 String* str = String::cast(value_array->get(i)); | 3044 String* str = String::cast(value_array->get(i)); |
3049 Object* symbol; | 3045 Object* internalized_str; |
3050 MaybeObject* maybe_symbol = heap->LookupSymbol(str); | 3046 MaybeObject* maybe_string = heap->InternalizeString(str); |
3051 if (maybe_symbol->ToObject(&symbol)) { | 3047 if (maybe_string->ToObject(&internalized_str)) { |
3052 value_array->set(i, symbol); | 3048 value_array->set(i, internalized_str); |
3053 } | 3049 } |
3054 } | 3050 } |
3055 } | 3051 } |
3056 // Convert backing store to a copy-on-write array. | 3052 // Convert backing store to a copy-on-write array. |
3057 value_array->set_map_no_write_barrier(heap->fixed_cow_array_map()); | 3053 value_array->set_map_no_write_barrier(heap->fixed_cow_array_map()); |
3058 } | 3054 } |
3059 | 3055 |
3060 | 3056 |
3061 void RegExpResultsCache::Clear(FixedArray* cache) { | 3057 void RegExpResultsCache::Clear(FixedArray* cache) { |
3062 for (int i = 0; i < kRegExpResultsCacheSize; i++) { | 3058 for (int i = 0; i < kRegExpResultsCacheSize; i++) { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3275 | 3271 |
3276 // Set pointer fields. | 3272 // Set pointer fields. |
3277 share->set_name(name); | 3273 share->set_name(name); |
3278 Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal); | 3274 Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal); |
3279 share->set_code(illegal); | 3275 share->set_code(illegal); |
3280 share->ClearOptimizedCodeMap(); | 3276 share->ClearOptimizedCodeMap(); |
3281 share->set_scope_info(ScopeInfo::Empty()); | 3277 share->set_scope_info(ScopeInfo::Empty()); |
3282 Code* construct_stub = | 3278 Code* construct_stub = |
3283 isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric); | 3279 isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric); |
3284 share->set_construct_stub(construct_stub); | 3280 share->set_construct_stub(construct_stub); |
3285 share->set_instance_class_name(Object_symbol()); | 3281 share->set_instance_class_name(Object_string()); |
3286 share->set_function_data(undefined_value(), SKIP_WRITE_BARRIER); | 3282 share->set_function_data(undefined_value(), SKIP_WRITE_BARRIER); |
3287 share->set_script(undefined_value(), SKIP_WRITE_BARRIER); | 3283 share->set_script(undefined_value(), SKIP_WRITE_BARRIER); |
3288 share->set_debug_info(undefined_value(), SKIP_WRITE_BARRIER); | 3284 share->set_debug_info(undefined_value(), SKIP_WRITE_BARRIER); |
3289 share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER); | 3285 share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER); |
3290 share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER); | 3286 share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER); |
3291 share->set_this_property_assignments(undefined_value(), SKIP_WRITE_BARRIER); | 3287 share->set_this_property_assignments(undefined_value(), SKIP_WRITE_BARRIER); |
3292 share->set_ast_node_count(0); | 3288 share->set_ast_node_count(0); |
3293 share->set_stress_deopt_counter(FLAG_deopt_every_n_times); | 3289 share->set_stress_deopt_counter(FLAG_deopt_every_n_times); |
3294 share->set_counters(0); | 3290 share->set_counters(0); |
3295 | 3291 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3341 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { | 3337 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { |
3342 // This makes uses of the the unsigned wraparound. | 3338 // This makes uses of the the unsigned wraparound. |
3343 return character - from <= to - from; | 3339 return character - from <= to - from; |
3344 } | 3340 } |
3345 | 3341 |
3346 | 3342 |
3347 MUST_USE_RESULT static inline MaybeObject* MakeOrFindTwoCharacterString( | 3343 MUST_USE_RESULT static inline MaybeObject* MakeOrFindTwoCharacterString( |
3348 Heap* heap, | 3344 Heap* heap, |
3349 uint16_t c1, | 3345 uint16_t c1, |
3350 uint16_t c2) { | 3346 uint16_t c2) { |
3351 String* symbol; | 3347 String* result; |
3352 // Numeric strings have a different hash algorithm not known by | 3348 // Numeric strings have a different hash algorithm not known by |
3353 // LookupTwoCharsSymbolIfExists, so we skip this step for such strings. | 3349 // LookupTwoCharsStringIfExists, so we skip this step for such strings. |
3354 if ((!Between(c1, '0', '9') || !Between(c2, '0', '9')) && | 3350 if ((!Between(c1, '0', '9') || !Between(c2, '0', '9')) && |
3355 heap->symbol_table()->LookupTwoCharsSymbolIfExists(c1, c2, &symbol)) { | 3351 heap->string_table()->LookupTwoCharsStringIfExists(c1, c2, &result)) { |
3356 return symbol; | 3352 return result; |
3357 // Now we know the length is 2, we might as well make use of that fact | 3353 // Now we know the length is 2, we might as well make use of that fact |
3358 // when building the new string. | 3354 // when building the new string. |
3359 } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) { | 3355 } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) { |
3360 // We can do this. | 3356 // We can do this. |
3361 ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this. | 3357 ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this. |
3362 Object* result; | 3358 Object* result; |
3363 { MaybeObject* maybe_result = heap->AllocateRawOneByteString(2); | 3359 { MaybeObject* maybe_result = heap->AllocateRawOneByteString(2); |
3364 if (!maybe_result->ToObject(&result)) return maybe_result; | 3360 if (!maybe_result->ToObject(&result)) return maybe_result; |
3365 } | 3361 } |
3366 uint8_t* dest = SeqOneByteString::cast(result)->GetChars(); | 3362 uint8_t* dest = SeqOneByteString::cast(result)->GetChars(); |
(...skipping 20 matching lines...) Expand all Loading... |
3387 } | 3383 } |
3388 | 3384 |
3389 int second_length = second->length(); | 3385 int second_length = second->length(); |
3390 if (second_length == 0) { | 3386 if (second_length == 0) { |
3391 return first; | 3387 return first; |
3392 } | 3388 } |
3393 | 3389 |
3394 int length = first_length + second_length; | 3390 int length = first_length + second_length; |
3395 | 3391 |
3396 // Optimization for 2-byte strings often used as keys in a decompression | 3392 // Optimization for 2-byte strings often used as keys in a decompression |
3397 // dictionary. Check whether we already have the string in the symbol | 3393 // dictionary. Check whether we already have the string in the string |
3398 // table to prevent creation of many unneccesary strings. | 3394 // table to prevent creation of many unneccesary strings. |
3399 if (length == 2) { | 3395 if (length == 2) { |
3400 uint16_t c1 = first->Get(0); | 3396 uint16_t c1 = first->Get(0); |
3401 uint16_t c2 = second->Get(0); | 3397 uint16_t c2 = second->Get(0); |
3402 return MakeOrFindTwoCharacterString(this, c1, c2); | 3398 return MakeOrFindTwoCharacterString(this, c1, c2); |
3403 } | 3399 } |
3404 | 3400 |
3405 bool first_is_one_byte = first->IsOneByteRepresentation(); | 3401 bool first_is_one_byte = first->IsOneByteRepresentation(); |
3406 bool second_is_one_byte = second->IsOneByteRepresentation(); | 3402 bool second_is_one_byte = second->IsOneByteRepresentation(); |
3407 bool is_one_byte = first_is_one_byte && second_is_one_byte; | 3403 bool is_one_byte = first_is_one_byte && second_is_one_byte; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3502 int start, | 3498 int start, |
3503 int end, | 3499 int end, |
3504 PretenureFlag pretenure) { | 3500 PretenureFlag pretenure) { |
3505 int length = end - start; | 3501 int length = end - start; |
3506 if (length <= 0) { | 3502 if (length <= 0) { |
3507 return empty_string(); | 3503 return empty_string(); |
3508 } else if (length == 1) { | 3504 } else if (length == 1) { |
3509 return LookupSingleCharacterStringFromCode(buffer->Get(start)); | 3505 return LookupSingleCharacterStringFromCode(buffer->Get(start)); |
3510 } else if (length == 2) { | 3506 } else if (length == 2) { |
3511 // Optimization for 2-byte strings often used as keys in a decompression | 3507 // Optimization for 2-byte strings often used as keys in a decompression |
3512 // dictionary. Check whether we already have the string in the symbol | 3508 // dictionary. Check whether we already have the string in the string |
3513 // table to prevent creation of many unneccesary strings. | 3509 // table to prevent creation of many unnecessary strings. |
3514 uint16_t c1 = buffer->Get(start); | 3510 uint16_t c1 = buffer->Get(start); |
3515 uint16_t c2 = buffer->Get(start + 1); | 3511 uint16_t c2 = buffer->Get(start + 1); |
3516 return MakeOrFindTwoCharacterString(this, c1, c2); | 3512 return MakeOrFindTwoCharacterString(this, c1, c2); |
3517 } | 3513 } |
3518 | 3514 |
3519 // Make an attempt to flatten the buffer to reduce access time. | 3515 // Make an attempt to flatten the buffer to reduce access time. |
3520 buffer = buffer->TryFlattenGetString(); | 3516 buffer = buffer->TryFlattenGetString(); |
3521 | 3517 |
3522 if (!FLAG_string_slices || | 3518 if (!FLAG_string_slices || |
3523 !buffer->IsFlat() || | 3519 !buffer->IsFlat() || |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3648 | 3644 |
3649 MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { | 3645 MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { |
3650 if (code <= String::kMaxOneByteCharCode) { | 3646 if (code <= String::kMaxOneByteCharCode) { |
3651 Object* value = single_character_string_cache()->get(code); | 3647 Object* value = single_character_string_cache()->get(code); |
3652 if (value != undefined_value()) return value; | 3648 if (value != undefined_value()) return value; |
3653 | 3649 |
3654 uint8_t buffer[1]; | 3650 uint8_t buffer[1]; |
3655 buffer[0] = static_cast<uint8_t>(code); | 3651 buffer[0] = static_cast<uint8_t>(code); |
3656 Object* result; | 3652 Object* result; |
3657 MaybeObject* maybe_result = | 3653 MaybeObject* maybe_result = |
3658 LookupOneByteSymbol(Vector<const uint8_t>(buffer, 1)); | 3654 InternalizeOneByteString(Vector<const uint8_t>(buffer, 1)); |
3659 | 3655 |
3660 if (!maybe_result->ToObject(&result)) return maybe_result; | 3656 if (!maybe_result->ToObject(&result)) return maybe_result; |
3661 single_character_string_cache()->set(code, result); | 3657 single_character_string_cache()->set(code, result); |
3662 return result; | 3658 return result; |
3663 } | 3659 } |
3664 | 3660 |
3665 Object* result; | 3661 Object* result; |
3666 { MaybeObject* maybe_result = AllocateRawTwoByteString(1); | 3662 { MaybeObject* maybe_result = AllocateRawTwoByteString(1); |
3667 if (!maybe_result->ToObject(&result)) return maybe_result; | 3663 if (!maybe_result->ToObject(&result)) return maybe_result; |
3668 } | 3664 } |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3957 if (!maybe_map->To(&new_map)) return maybe_map; | 3953 if (!maybe_map->To(&new_map)) return maybe_map; |
3958 | 3954 |
3959 Object* prototype; | 3955 Object* prototype; |
3960 MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map); | 3956 MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map); |
3961 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; | 3957 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; |
3962 | 3958 |
3963 // When creating the prototype for the function we must set its | 3959 // When creating the prototype for the function we must set its |
3964 // constructor to the function. | 3960 // constructor to the function. |
3965 MaybeObject* maybe_failure = | 3961 MaybeObject* maybe_failure = |
3966 JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes( | 3962 JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes( |
3967 constructor_symbol(), function, DONT_ENUM); | 3963 constructor_string(), function, DONT_ENUM); |
3968 if (maybe_failure->IsFailure()) return maybe_failure; | 3964 if (maybe_failure->IsFailure()) return maybe_failure; |
3969 | 3965 |
3970 return prototype; | 3966 return prototype; |
3971 } | 3967 } |
3972 | 3968 |
3973 | 3969 |
3974 MaybeObject* Heap::AllocateFunction(Map* function_map, | 3970 MaybeObject* Heap::AllocateFunction(Map* function_map, |
3975 SharedFunctionInfo* shared, | 3971 SharedFunctionInfo* shared, |
3976 Object* prototype, | 3972 Object* prototype, |
3977 PretenureFlag pretenure) { | 3973 PretenureFlag pretenure) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4096 // Inline constructor can only handle inobject properties. | 4092 // Inline constructor can only handle inobject properties. |
4097 fun->shared()->ForbidInlineConstructor(); | 4093 fun->shared()->ForbidInlineConstructor(); |
4098 } else { | 4094 } else { |
4099 DescriptorArray* descriptors; | 4095 DescriptorArray* descriptors; |
4100 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(count); | 4096 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(count); |
4101 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 4097 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; |
4102 | 4098 |
4103 DescriptorArray::WhitenessWitness witness(descriptors); | 4099 DescriptorArray::WhitenessWitness witness(descriptors); |
4104 for (int i = 0; i < count; i++) { | 4100 for (int i = 0; i < count; i++) { |
4105 String* name = fun->shared()->GetThisPropertyAssignmentName(i); | 4101 String* name = fun->shared()->GetThisPropertyAssignmentName(i); |
4106 ASSERT(name->IsSymbol()); | 4102 ASSERT(name->IsInternalizedString()); |
4107 FieldDescriptor field(name, i, NONE, i + 1); | 4103 FieldDescriptor field(name, i, NONE, i + 1); |
4108 descriptors->Set(i, &field, witness); | 4104 descriptors->Set(i, &field, witness); |
4109 } | 4105 } |
4110 descriptors->Sort(); | 4106 descriptors->Sort(); |
4111 | 4107 |
4112 // The descriptors may contain duplicates because the compiler does not | 4108 // The descriptors may contain duplicates because the compiler does not |
4113 // guarantee the uniqueness of property names (it would have required | 4109 // guarantee the uniqueness of property names (it would have required |
4114 // quadratic time). Once the descriptors are sorted we can check for | 4110 // quadratic time). Once the descriptors are sorted we can check for |
4115 // duplicates in linear time. | 4111 // duplicates in linear time. |
4116 if (HasDuplicates(descriptors)) { | 4112 if (HasDuplicates(descriptors)) { |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4526 // Allocate the backing storage for the properties. | 4522 // Allocate the backing storage for the properties. |
4527 int prop_size = map->unused_property_fields() - map->inobject_properties(); | 4523 int prop_size = map->unused_property_fields() - map->inobject_properties(); |
4528 Object* properties; | 4524 Object* properties; |
4529 maybe = AllocateFixedArray(prop_size, TENURED); | 4525 maybe = AllocateFixedArray(prop_size, TENURED); |
4530 if (!maybe->ToObject(&properties)) return maybe; | 4526 if (!maybe->ToObject(&properties)) return maybe; |
4531 | 4527 |
4532 // Functions require some allocation, which might fail here. | 4528 // Functions require some allocation, which might fail here. |
4533 SharedFunctionInfo* shared = NULL; | 4529 SharedFunctionInfo* shared = NULL; |
4534 if (type == JS_FUNCTION_TYPE) { | 4530 if (type == JS_FUNCTION_TYPE) { |
4535 String* name; | 4531 String* name; |
4536 maybe = LookupOneByteSymbol(STATIC_ASCII_VECTOR("<freezing call trap>")); | 4532 maybe = |
| 4533 InternalizeOneByteString(STATIC_ASCII_VECTOR("<freezing call trap>")); |
4537 if (!maybe->To<String>(&name)) return maybe; | 4534 if (!maybe->To<String>(&name)) return maybe; |
4538 maybe = AllocateSharedFunctionInfo(name); | 4535 maybe = AllocateSharedFunctionInfo(name); |
4539 if (!maybe->To<SharedFunctionInfo>(&shared)) return maybe; | 4536 if (!maybe->To<SharedFunctionInfo>(&shared)) return maybe; |
4540 } | 4537 } |
4541 | 4538 |
4542 // Because of possible retries of this function after failure, | 4539 // Because of possible retries of this function after failure, |
4543 // we must NOT fail after this point, where we have changed the type! | 4540 // we must NOT fail after this point, where we have changed the type! |
4544 | 4541 |
4545 // Reset the map for the object. | 4542 // Reset the map for the object. |
4546 object->set_map(map); | 4543 object->set_map(map); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4660 CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length); | 4657 CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length); |
4661 } else { // It's not a one byte string. | 4658 } else { // It's not a one byte string. |
4662 MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure); | 4659 MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure); |
4663 if (!maybe_result->ToObject(&result)) return maybe_result; | 4660 if (!maybe_result->ToObject(&result)) return maybe_result; |
4664 CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length); | 4661 CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length); |
4665 } | 4662 } |
4666 return result; | 4663 return result; |
4667 } | 4664 } |
4668 | 4665 |
4669 | 4666 |
4670 Map* Heap::SymbolMapForString(String* string) { | 4667 Map* Heap::InternalizedStringMapForString(String* string) { |
4671 // If the string is in new space it cannot be used as a symbol. | 4668 // If the string is in new space it cannot be used as internalized. |
4672 if (InNewSpace(string)) return NULL; | 4669 if (InNewSpace(string)) return NULL; |
4673 | 4670 |
4674 // Find the corresponding symbol map for strings. | 4671 // Find the corresponding internalized string map for strings. |
4675 switch (string->map()->instance_type()) { | 4672 switch (string->map()->instance_type()) { |
4676 case STRING_TYPE: return symbol_map(); | 4673 case STRING_TYPE: return internalized_string_map(); |
4677 case ASCII_STRING_TYPE: return ascii_symbol_map(); | 4674 case ASCII_STRING_TYPE: return ascii_internalized_string_map(); |
4678 case CONS_STRING_TYPE: return cons_symbol_map(); | 4675 case CONS_STRING_TYPE: return cons_internalized_string_map(); |
4679 case CONS_ASCII_STRING_TYPE: return cons_ascii_symbol_map(); | 4676 case CONS_ASCII_STRING_TYPE: return cons_ascii_internalized_string_map(); |
4680 case EXTERNAL_STRING_TYPE: return external_symbol_map(); | 4677 case EXTERNAL_STRING_TYPE: return external_internalized_string_map(); |
4681 case EXTERNAL_ASCII_STRING_TYPE: return external_ascii_symbol_map(); | 4678 case EXTERNAL_ASCII_STRING_TYPE: |
| 4679 return external_ascii_internalized_string_map(); |
4682 case EXTERNAL_STRING_WITH_ASCII_DATA_TYPE: | 4680 case EXTERNAL_STRING_WITH_ASCII_DATA_TYPE: |
4683 return external_symbol_with_ascii_data_map(); | 4681 return external_internalized_string_with_ascii_data_map(); |
4684 case SHORT_EXTERNAL_STRING_TYPE: return short_external_symbol_map(); | 4682 case SHORT_EXTERNAL_STRING_TYPE: |
| 4683 return short_external_internalized_string_map(); |
4685 case SHORT_EXTERNAL_ASCII_STRING_TYPE: | 4684 case SHORT_EXTERNAL_ASCII_STRING_TYPE: |
4686 return short_external_ascii_symbol_map(); | 4685 return short_external_ascii_internalized_string_map(); |
4687 case SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE: | 4686 case SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE: |
4688 return short_external_symbol_with_ascii_data_map(); | 4687 return short_external_internalized_string_with_ascii_data_map(); |
4689 default: return NULL; // No match found. | 4688 default: return NULL; // No match found. |
4690 } | 4689 } |
4691 } | 4690 } |
4692 | 4691 |
4693 | 4692 |
4694 static inline void WriteOneByteData(Vector<const char> vector, | 4693 static inline void WriteOneByteData(Vector<const char> vector, |
4695 uint8_t* chars, | 4694 uint8_t* chars, |
4696 int len) { | 4695 int len) { |
4697 // Only works for ascii. | 4696 // Only works for ascii. |
4698 ASSERT(vector.length() == len); | 4697 ASSERT(vector.length() == len); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4732 String::WriteToFlat(s, chars, 0, len); | 4731 String::WriteToFlat(s, chars, 0, len); |
4733 } | 4732 } |
4734 | 4733 |
4735 static inline void WriteTwoByteData(String* s, uint16_t* chars, int len) { | 4734 static inline void WriteTwoByteData(String* s, uint16_t* chars, int len) { |
4736 ASSERT(s->length() == len); | 4735 ASSERT(s->length() == len); |
4737 String::WriteToFlat(s, chars, 0, len); | 4736 String::WriteToFlat(s, chars, 0, len); |
4738 } | 4737 } |
4739 | 4738 |
4740 | 4739 |
4741 template<bool is_one_byte, typename T> | 4740 template<bool is_one_byte, typename T> |
4742 MaybeObject* Heap::AllocateInternalSymbol(T t, | 4741 MaybeObject* Heap::AllocateInternalizedStringImpl( |
4743 int chars, | 4742 T t, int chars, uint32_t hash_field) { |
4744 uint32_t hash_field) { | |
4745 ASSERT(chars >= 0); | 4743 ASSERT(chars >= 0); |
4746 // Compute map and object size. | 4744 // Compute map and object size. |
4747 int size; | 4745 int size; |
4748 Map* map; | 4746 Map* map; |
4749 | 4747 |
4750 if (is_one_byte) { | 4748 if (is_one_byte) { |
4751 if (chars > SeqOneByteString::kMaxLength) { | 4749 if (chars > SeqOneByteString::kMaxLength) { |
4752 return Failure::OutOfMemoryException(0x9); | 4750 return Failure::OutOfMemoryException(0x9); |
4753 } | 4751 } |
4754 map = ascii_symbol_map(); | 4752 map = ascii_internalized_string_map(); |
4755 size = SeqOneByteString::SizeFor(chars); | 4753 size = SeqOneByteString::SizeFor(chars); |
4756 } else { | 4754 } else { |
4757 if (chars > SeqTwoByteString::kMaxLength) { | 4755 if (chars > SeqTwoByteString::kMaxLength) { |
4758 return Failure::OutOfMemoryException(0xa); | 4756 return Failure::OutOfMemoryException(0xa); |
4759 } | 4757 } |
4760 map = symbol_map(); | 4758 map = internalized_string_map(); |
4761 size = SeqTwoByteString::SizeFor(chars); | 4759 size = SeqTwoByteString::SizeFor(chars); |
4762 } | 4760 } |
4763 | 4761 |
4764 // Allocate string. | 4762 // Allocate string. |
4765 Object* result; | 4763 Object* result; |
4766 { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) | 4764 { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) |
4767 ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) | 4765 ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) |
4768 : old_data_space_->AllocateRaw(size); | 4766 : old_data_space_->AllocateRaw(size); |
4769 if (!maybe_result->ToObject(&result)) return maybe_result; | 4767 if (!maybe_result->ToObject(&result)) return maybe_result; |
4770 } | 4768 } |
(...skipping 10 matching lines...) Expand all Loading... |
4781 WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars); | 4779 WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars); |
4782 } else { | 4780 } else { |
4783 WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars); | 4781 WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars); |
4784 } | 4782 } |
4785 return answer; | 4783 return answer; |
4786 } | 4784 } |
4787 | 4785 |
4788 | 4786 |
4789 // Need explicit instantiations. | 4787 // Need explicit instantiations. |
4790 template | 4788 template |
4791 MaybeObject* Heap::AllocateInternalSymbol<true>(String*, int, uint32_t); | 4789 MaybeObject* Heap::AllocateInternalizedStringImpl<true>(String*, int, uint32_t); |
4792 template | 4790 template |
4793 MaybeObject* Heap::AllocateInternalSymbol<false>(String*, int, uint32_t); | 4791 MaybeObject* Heap::AllocateInternalizedStringImpl<false>( |
| 4792 String*, int, uint32_t); |
4794 template | 4793 template |
4795 MaybeObject* Heap::AllocateInternalSymbol<false>(Vector<const char>, | 4794 MaybeObject* Heap::AllocateInternalizedStringImpl<false>( |
4796 int, | 4795 Vector<const char>, int, uint32_t); |
4797 uint32_t); | |
4798 | 4796 |
4799 | 4797 |
4800 MaybeObject* Heap::AllocateRawOneByteString(int length, | 4798 MaybeObject* Heap::AllocateRawOneByteString(int length, |
4801 PretenureFlag pretenure) { | 4799 PretenureFlag pretenure) { |
4802 if (length < 0 || length > SeqOneByteString::kMaxLength) { | 4800 if (length < 0 || length > SeqOneByteString::kMaxLength) { |
4803 return Failure::OutOfMemoryException(0xb); | 4801 return Failure::OutOfMemoryException(0xb); |
4804 } | 4802 } |
4805 | 4803 |
4806 int size = SeqOneByteString::SizeFor(length); | 4804 int size = SeqOneByteString::SizeFor(length); |
4807 ASSERT(size <= SeqOneByteString::kMaxSize); | 4805 ASSERT(size <= SeqOneByteString::kMaxSize); |
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5658 VerifyPointersVisitor no_dirty_regions_visitor; | 5656 VerifyPointersVisitor no_dirty_regions_visitor; |
5659 old_data_space_->Verify(&no_dirty_regions_visitor); | 5657 old_data_space_->Verify(&no_dirty_regions_visitor); |
5660 code_space_->Verify(&no_dirty_regions_visitor); | 5658 code_space_->Verify(&no_dirty_regions_visitor); |
5661 cell_space_->Verify(&no_dirty_regions_visitor); | 5659 cell_space_->Verify(&no_dirty_regions_visitor); |
5662 | 5660 |
5663 lo_space_->Verify(); | 5661 lo_space_->Verify(); |
5664 } | 5662 } |
5665 #endif | 5663 #endif |
5666 | 5664 |
5667 | 5665 |
5668 MaybeObject* Heap::LookupUtf8Symbol(Vector<const char> string) { | 5666 MaybeObject* Heap::InternalizeUtf8String(Vector<const char> string) { |
5669 Object* symbol = NULL; | 5667 Object* result = NULL; |
5670 Object* new_table; | 5668 Object* new_table; |
5671 { MaybeObject* maybe_new_table = | 5669 { MaybeObject* maybe_new_table = |
5672 symbol_table()->LookupUtf8Symbol(string, &symbol); | 5670 string_table()->LookupUtf8String(string, &result); |
5673 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 5671 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
5674 } | 5672 } |
5675 // Can't use set_symbol_table because SymbolTable::cast knows that | 5673 // Can't use set_string_table because StringTable::cast knows that |
5676 // SymbolTable is a singleton and checks for identity. | 5674 // StringTable is a singleton and checks for identity. |
5677 roots_[kSymbolTableRootIndex] = new_table; | 5675 roots_[kStringTableRootIndex] = new_table; |
5678 ASSERT(symbol != NULL); | 5676 ASSERT(result != NULL); |
5679 return symbol; | 5677 return result; |
5680 } | 5678 } |
5681 | 5679 |
5682 | 5680 |
5683 MaybeObject* Heap::LookupOneByteSymbol(Vector<const uint8_t> string) { | 5681 MaybeObject* Heap::InternalizeOneByteString(Vector<const uint8_t> string) { |
5684 Object* symbol = NULL; | 5682 Object* result = NULL; |
5685 Object* new_table; | 5683 Object* new_table; |
5686 { MaybeObject* maybe_new_table = | 5684 { MaybeObject* maybe_new_table = |
5687 symbol_table()->LookupOneByteSymbol(string, &symbol); | 5685 string_table()->LookupOneByteString(string, &result); |
5688 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 5686 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
5689 } | 5687 } |
5690 // Can't use set_symbol_table because SymbolTable::cast knows that | 5688 // Can't use set_string_table because StringTable::cast knows that |
5691 // SymbolTable is a singleton and checks for identity. | 5689 // StringTable is a singleton and checks for identity. |
5692 roots_[kSymbolTableRootIndex] = new_table; | 5690 roots_[kStringTableRootIndex] = new_table; |
5693 ASSERT(symbol != NULL); | 5691 ASSERT(result != NULL); |
5694 return symbol; | 5692 return result; |
5695 } | 5693 } |
5696 | 5694 |
5697 | 5695 |
5698 MaybeObject* Heap::LookupOneByteSymbol(Handle<SeqOneByteString> string, | 5696 MaybeObject* Heap::InternalizeOneByteString(Handle<SeqOneByteString> string, |
5699 int from, | 5697 int from, |
5700 int length) { | 5698 int length) { |
5701 Object* symbol = NULL; | 5699 Object* result = NULL; |
5702 Object* new_table; | 5700 Object* new_table; |
5703 { MaybeObject* maybe_new_table = | 5701 { MaybeObject* maybe_new_table = |
5704 symbol_table()->LookupSubStringOneByteSymbol(string, | 5702 string_table()->LookupSubStringOneByteString(string, |
5705 from, | 5703 from, |
5706 length, | 5704 length, |
5707 &symbol); | 5705 &result); |
5708 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 5706 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
5709 } | 5707 } |
5710 // Can't use set_symbol_table because SymbolTable::cast knows that | 5708 // Can't use set_string_table because StringTable::cast knows that |
5711 // SymbolTable is a singleton and checks for identity. | 5709 // StringTable is a singleton and checks for identity. |
5712 roots_[kSymbolTableRootIndex] = new_table; | 5710 roots_[kStringTableRootIndex] = new_table; |
5713 ASSERT(symbol != NULL); | 5711 ASSERT(result != NULL); |
5714 return symbol; | 5712 return result; |
5715 } | 5713 } |
5716 | 5714 |
5717 | 5715 |
5718 MaybeObject* Heap::LookupTwoByteSymbol(Vector<const uc16> string) { | 5716 MaybeObject* Heap::InternalizeTwoByteString(Vector<const uc16> string) { |
5719 Object* symbol = NULL; | 5717 Object* result = NULL; |
5720 Object* new_table; | 5718 Object* new_table; |
5721 { MaybeObject* maybe_new_table = | 5719 { MaybeObject* maybe_new_table = |
5722 symbol_table()->LookupTwoByteSymbol(string, &symbol); | 5720 string_table()->LookupTwoByteString(string, &result); |
5723 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 5721 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
5724 } | 5722 } |
5725 // Can't use set_symbol_table because SymbolTable::cast knows that | 5723 // Can't use set_string_table because StringTable::cast knows that |
5726 // SymbolTable is a singleton and checks for identity. | 5724 // StringTable is a singleton and checks for identity. |
5727 roots_[kSymbolTableRootIndex] = new_table; | 5725 roots_[kStringTableRootIndex] = new_table; |
5728 ASSERT(symbol != NULL); | 5726 ASSERT(result != NULL); |
5729 return symbol; | 5727 return result; |
5730 } | 5728 } |
5731 | 5729 |
5732 | 5730 |
5733 MaybeObject* Heap::LookupSymbol(String* string) { | 5731 MaybeObject* Heap::InternalizeString(String* string) { |
5734 if (string->IsSymbol()) return string; | 5732 if (string->IsInternalizedString()) return string; |
5735 Object* symbol = NULL; | 5733 Object* result = NULL; |
5736 Object* new_table; | 5734 Object* new_table; |
5737 { MaybeObject* maybe_new_table = | 5735 { MaybeObject* maybe_new_table = |
5738 symbol_table()->LookupString(string, &symbol); | 5736 string_table()->LookupString(string, &result); |
5739 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 5737 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
5740 } | 5738 } |
5741 // Can't use set_symbol_table because SymbolTable::cast knows that | 5739 // Can't use set_string_table because StringTable::cast knows that |
5742 // SymbolTable is a singleton and checks for identity. | 5740 // StringTable is a singleton and checks for identity. |
5743 roots_[kSymbolTableRootIndex] = new_table; | 5741 roots_[kStringTableRootIndex] = new_table; |
5744 ASSERT(symbol != NULL); | 5742 ASSERT(result != NULL); |
5745 return symbol; | 5743 return result; |
5746 } | 5744 } |
5747 | 5745 |
5748 | 5746 |
5749 bool Heap::LookupSymbolIfExists(String* string, String** symbol) { | 5747 bool Heap::InternalizeStringIfExists(String* string, String** result) { |
5750 if (string->IsSymbol()) { | 5748 if (string->IsInternalizedString()) { |
5751 *symbol = string; | 5749 *result = string; |
5752 return true; | 5750 return true; |
5753 } | 5751 } |
5754 return symbol_table()->LookupSymbolIfExists(string, symbol); | 5752 return string_table()->LookupStringIfExists(string, result); |
5755 } | 5753 } |
5756 | 5754 |
5757 | 5755 |
5758 void Heap::ZapFromSpace() { | 5756 void Heap::ZapFromSpace() { |
5759 NewSpacePageIterator it(new_space_.FromSpaceStart(), | 5757 NewSpacePageIterator it(new_space_.FromSpaceStart(), |
5760 new_space_.FromSpaceEnd()); | 5758 new_space_.FromSpaceEnd()); |
5761 while (it.has_next()) { | 5759 while (it.has_next()) { |
5762 NewSpacePage* page = it.next(); | 5760 NewSpacePage* page = it.next(); |
5763 for (Address cursor = page->area_start(), limit = page->area_end(); | 5761 for (Address cursor = page->area_start(), limit = page->area_end(); |
5764 cursor < limit; | 5762 cursor < limit; |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5972 #endif | 5970 #endif |
5973 | 5971 |
5974 | 5972 |
5975 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { | 5973 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { |
5976 IterateStrongRoots(v, mode); | 5974 IterateStrongRoots(v, mode); |
5977 IterateWeakRoots(v, mode); | 5975 IterateWeakRoots(v, mode); |
5978 } | 5976 } |
5979 | 5977 |
5980 | 5978 |
5981 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { | 5979 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { |
5982 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); | 5980 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex])); |
5983 v->Synchronize(VisitorSynchronization::kSymbolTable); | 5981 v->Synchronize(VisitorSynchronization::kStringTable); |
5984 if (mode != VISIT_ALL_IN_SCAVENGE && | 5982 if (mode != VISIT_ALL_IN_SCAVENGE && |
5985 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { | 5983 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { |
5986 // Scavenge collections have special processing for this. | 5984 // Scavenge collections have special processing for this. |
5987 external_string_table_.Iterate(v); | 5985 external_string_table_.Iterate(v); |
5988 error_object_list_.Iterate(v); | 5986 error_object_list_.Iterate(v); |
5989 } | 5987 } |
5990 v->Synchronize(VisitorSynchronization::kExternalStringsTable); | 5988 v->Synchronize(VisitorSynchronization::kExternalStringsTable); |
5991 } | 5989 } |
5992 | 5990 |
5993 | 5991 |
5994 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { | 5992 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { |
5995 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); | 5993 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); |
5996 v->Synchronize(VisitorSynchronization::kStrongRootList); | 5994 v->Synchronize(VisitorSynchronization::kStrongRootList); |
5997 | 5995 |
5998 v->VisitPointer(BitCast<Object**>(&hidden_symbol_)); | 5996 v->VisitPointer(BitCast<Object**>(&hidden_string_)); |
5999 v->Synchronize(VisitorSynchronization::kSymbol); | 5997 v->Synchronize(VisitorSynchronization::kInternalizedString); |
6000 | 5998 |
6001 isolate_->bootstrapper()->Iterate(v); | 5999 isolate_->bootstrapper()->Iterate(v); |
6002 v->Synchronize(VisitorSynchronization::kBootstrapper); | 6000 v->Synchronize(VisitorSynchronization::kBootstrapper); |
6003 isolate_->Iterate(v); | 6001 isolate_->Iterate(v); |
6004 v->Synchronize(VisitorSynchronization::kTop); | 6002 v->Synchronize(VisitorSynchronization::kTop); |
6005 Relocatable::Iterate(v); | 6003 Relocatable::Iterate(v); |
6006 v->Synchronize(VisitorSynchronization::kRelocatable); | 6004 v->Synchronize(VisitorSynchronization::kRelocatable); |
6007 | 6005 |
6008 #ifdef ENABLE_DEBUGGER_SUPPORT | 6006 #ifdef ENABLE_DEBUGGER_SUPPORT |
6009 isolate_->debug()->Iterate(v); | 6007 isolate_->debug()->Iterate(v); |
(...skipping 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7174 Key& key = keys_[index + i]; | 7172 Key& key = keys_[index + i]; |
7175 if ((key.map == map) && key.name->Equals(name)) { | 7173 if ((key.map == map) && key.name->Equals(name)) { |
7176 return field_offsets_[index + i]; | 7174 return field_offsets_[index + i]; |
7177 } | 7175 } |
7178 } | 7176 } |
7179 return kNotFound; | 7177 return kNotFound; |
7180 } | 7178 } |
7181 | 7179 |
7182 | 7180 |
7183 void KeyedLookupCache::Update(Map* map, String* name, int field_offset) { | 7181 void KeyedLookupCache::Update(Map* map, String* name, int field_offset) { |
7184 String* symbol; | 7182 String* internalized_name; |
7185 if (HEAP->LookupSymbolIfExists(name, &symbol)) { | 7183 if (HEAP->InternalizeStringIfExists(name, &internalized_name)) { |
7186 int index = (Hash(map, symbol) & kHashMask); | 7184 int index = (Hash(map, internalized_name) & kHashMask); |
7187 // After a GC there will be free slots, so we use them in order (this may | 7185 // After a GC there will be free slots, so we use them in order (this may |
7188 // help to get the most frequently used one in position 0). | 7186 // help to get the most frequently used one in position 0). |
7189 for (int i = 0; i< kEntriesPerBucket; i++) { | 7187 for (int i = 0; i< kEntriesPerBucket; i++) { |
7190 Key& key = keys_[index]; | 7188 Key& key = keys_[index]; |
7191 Object* free_entry_indicator = NULL; | 7189 Object* free_entry_indicator = NULL; |
7192 if (key.map == free_entry_indicator) { | 7190 if (key.map == free_entry_indicator) { |
7193 key.map = map; | 7191 key.map = map; |
7194 key.name = symbol; | 7192 key.name = internalized_name; |
7195 field_offsets_[index + i] = field_offset; | 7193 field_offsets_[index + i] = field_offset; |
7196 return; | 7194 return; |
7197 } | 7195 } |
7198 } | 7196 } |
7199 // No free entry found in this bucket, so we move them all down one and | 7197 // No free entry found in this bucket, so we move them all down one and |
7200 // put the new entry at position zero. | 7198 // put the new entry at position zero. |
7201 for (int i = kEntriesPerBucket - 1; i > 0; i--) { | 7199 for (int i = kEntriesPerBucket - 1; i > 0; i--) { |
7202 Key& key = keys_[index + i]; | 7200 Key& key = keys_[index + i]; |
7203 Key& key2 = keys_[index + i - 1]; | 7201 Key& key2 = keys_[index + i - 1]; |
7204 key = key2; | 7202 key = key2; |
7205 field_offsets_[index + i] = field_offsets_[index + i - 1]; | 7203 field_offsets_[index + i] = field_offsets_[index + i - 1]; |
7206 } | 7204 } |
7207 | 7205 |
7208 // Write the new first entry. | 7206 // Write the new first entry. |
7209 Key& key = keys_[index]; | 7207 Key& key = keys_[index]; |
7210 key.map = map; | 7208 key.map = map; |
7211 key.name = symbol; | 7209 key.name = internalized_name; |
7212 field_offsets_[index] = field_offset; | 7210 field_offsets_[index] = field_offset; |
7213 } | 7211 } |
7214 } | 7212 } |
7215 | 7213 |
7216 | 7214 |
7217 void KeyedLookupCache::Clear() { | 7215 void KeyedLookupCache::Clear() { |
7218 for (int index = 0; index < kLength; index++) keys_[index].map = NULL; | 7216 for (int index = 0; index < kLength; index++) keys_[index].map = NULL; |
7219 } | 7217 } |
7220 | 7218 |
7221 | 7219 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7334 } | 7332 } |
7335 | 7333 |
7336 | 7334 |
7337 void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) { | 7335 void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) { |
7338 // If formatting the stack trace causes a GC, this method will be | 7336 // If formatting the stack trace causes a GC, this method will be |
7339 // recursively called. In that case, skip the recursive call, since | 7337 // recursively called. In that case, skip the recursive call, since |
7340 // the loop modifies the list while iterating over it. | 7338 // the loop modifies the list while iterating over it. |
7341 if (nested_ || list_.is_empty() || isolate->has_pending_exception()) return; | 7339 if (nested_ || list_.is_empty() || isolate->has_pending_exception()) return; |
7342 nested_ = true; | 7340 nested_ = true; |
7343 HandleScope scope(isolate); | 7341 HandleScope scope(isolate); |
7344 Handle<String> stack_key = isolate->factory()->stack_symbol(); | 7342 Handle<String> stack_key = isolate->factory()->stack_string(); |
7345 int write_index = 0; | 7343 int write_index = 0; |
7346 int budget = kBudgetPerGC; | 7344 int budget = kBudgetPerGC; |
7347 for (int i = 0; i < list_.length(); i++) { | 7345 for (int i = 0; i < list_.length(); i++) { |
7348 Object* object = list_[i]; | 7346 Object* object = list_[i]; |
7349 JSFunction* getter_fun; | 7347 JSFunction* getter_fun; |
7350 | 7348 |
7351 { AssertNoAllocation assert; | 7349 { AssertNoAllocation assert; |
7352 // Skip possible holes in the list. | 7350 // Skip possible holes in the list. |
7353 if (object->IsTheHole()) continue; | 7351 if (object->IsTheHole()) continue; |
7354 if (isolate->heap()->InNewSpace(object) || budget == 0) { | 7352 if (isolate->heap()->InNewSpace(object) || budget == 0) { |
7355 list_[write_index++] = object; | 7353 list_[write_index++] = object; |
7356 continue; | 7354 continue; |
7357 } | 7355 } |
7358 | 7356 |
7359 // Check whether the stack property is backed by the original getter. | 7357 // Check whether the stack property is backed by the original getter. |
7360 LookupResult lookup(isolate); | 7358 LookupResult lookup(isolate); |
7361 JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup); | 7359 JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup); |
7362 if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue; | 7360 if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue; |
7363 Object* callback = lookup.GetCallbackObject(); | 7361 Object* callback = lookup.GetCallbackObject(); |
7364 if (!callback->IsAccessorPair()) continue; | 7362 if (!callback->IsAccessorPair()) continue; |
7365 Object* getter_obj = AccessorPair::cast(callback)->getter(); | 7363 Object* getter_obj = AccessorPair::cast(callback)->getter(); |
7366 if (!getter_obj->IsJSFunction()) continue; | 7364 if (!getter_obj->IsJSFunction()) continue; |
7367 getter_fun = JSFunction::cast(getter_obj); | 7365 getter_fun = JSFunction::cast(getter_obj); |
7368 String* key = isolate->heap()->hidden_stack_trace_symbol(); | 7366 String* key = isolate->heap()->hidden_stack_trace_string(); |
7369 if (key != getter_fun->GetHiddenProperty(key)) continue; | 7367 if (key != getter_fun->GetHiddenProperty(key)) continue; |
7370 } | 7368 } |
7371 | 7369 |
7372 budget--; | 7370 budget--; |
7373 HandleScope scope(isolate); | 7371 HandleScope scope(isolate); |
7374 bool has_exception = false; | 7372 bool has_exception = false; |
7375 #ifdef DEBUG | 7373 #ifdef DEBUG |
7376 Handle<Map> map(HeapObject::cast(object)->map(), isolate); | 7374 Handle<Map> map(HeapObject::cast(object)->map(), isolate); |
7377 #endif | 7375 #endif |
7378 Handle<Object> object_handle(object, isolate); | 7376 Handle<Object> object_handle(object, isolate); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7530 static_cast<int>(object_sizes_last_time_[index])); | 7528 static_cast<int>(object_sizes_last_time_[index])); |
7531 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) | 7529 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) |
7532 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7530 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
7533 | 7531 |
7534 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7532 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
7535 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7533 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
7536 ClearObjectStats(); | 7534 ClearObjectStats(); |
7537 } | 7535 } |
7538 | 7536 |
7539 } } // namespace v8::internal | 7537 } } // namespace v8::internal |
OLD | NEW |