Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1638)

Side by Side Diff: src/heap.cc

Issue 12210083: Renamed "symbols" to "internalized strings" throughout the code base, (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Yang's comments Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698