OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 | 77 |
78 // semispace_size_ should be a power of 2 and old_generation_size_ should be | 78 // semispace_size_ should be a power of 2 and old_generation_size_ should be |
79 // a multiple of Page::kPageSize. | 79 // a multiple of Page::kPageSize. |
80 int Heap::semispace_size_ = 2*MB; | 80 int Heap::semispace_size_ = 2*MB; |
81 int Heap::old_generation_size_ = 512*MB; | 81 int Heap::old_generation_size_ = 512*MB; |
82 int Heap::initial_semispace_size_ = 256*KB; | 82 int Heap::initial_semispace_size_ = 256*KB; |
83 | 83 |
84 GCCallback Heap::global_gc_prologue_callback_ = NULL; | 84 GCCallback Heap::global_gc_prologue_callback_ = NULL; |
85 GCCallback Heap::global_gc_epilogue_callback_ = NULL; | 85 GCCallback Heap::global_gc_epilogue_callback_ = NULL; |
86 | 86 |
| 87 ExternalSymbolCallback Heap::global_external_symbol_callback_ = NULL; |
| 88 |
87 // Variables set based on semispace_size_ and old_generation_size_ in | 89 // Variables set based on semispace_size_ and old_generation_size_ in |
88 // ConfigureHeap. | 90 // ConfigureHeap. |
89 int Heap::young_generation_size_ = 0; // Will be 2 * semispace_size_. | 91 int Heap::young_generation_size_ = 0; // Will be 2 * semispace_size_. |
90 | 92 |
91 // Double the new space after this many scavenge collections. | 93 // Double the new space after this many scavenge collections. |
92 int Heap::new_space_growth_limit_ = 8; | 94 int Heap::new_space_growth_limit_ = 8; |
93 int Heap::scavenge_count_ = 0; | 95 int Heap::scavenge_count_ = 0; |
94 Heap::HeapState Heap::gc_state_ = NOT_IN_GC; | 96 Heap::HeapState Heap::gc_state_ = NOT_IN_GC; |
95 | 97 |
96 int Heap::mc_count_ = 0; | 98 int Heap::mc_count_ = 0; |
(...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1528 if (result->IsFailure()) return result; | 1530 if (result->IsFailure()) return result; |
1529 | 1531 |
1530 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); | 1532 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); |
1531 external_string->set_length(length); | 1533 external_string->set_length(length); |
1532 external_string->set_resource(resource); | 1534 external_string->set_resource(resource); |
1533 | 1535 |
1534 return result; | 1536 return result; |
1535 } | 1537 } |
1536 | 1538 |
1537 | 1539 |
| 1540 Object* Heap::AllocateExternalSymbolFromTwoByte( |
| 1541 ExternalTwoByteString::Resource* resource) { |
| 1542 Map* map; |
| 1543 int length = resource->length(); |
| 1544 if (length <= String::kMaxShortStringSize) { |
| 1545 map = short_external_symbol_map(); |
| 1546 } else if (length <= String::kMaxMediumStringSize) { |
| 1547 map = medium_external_symbol_map(); |
| 1548 } else { |
| 1549 map = long_external_symbol_map(); |
| 1550 } |
| 1551 |
| 1552 Object* result = Allocate(map, OLD_DATA_SPACE); |
| 1553 if (result->IsFailure()) return result; |
| 1554 |
| 1555 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); |
| 1556 external_string->set_length(length); |
| 1557 external_string->set_resource(resource); |
| 1558 |
| 1559 return result; |
| 1560 } |
| 1561 |
| 1562 |
1538 Object* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { | 1563 Object* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { |
1539 if (code <= String::kMaxAsciiCharCode) { | 1564 if (code <= String::kMaxAsciiCharCode) { |
1540 Object* value = Heap::single_character_string_cache()->get(code); | 1565 Object* value = Heap::single_character_string_cache()->get(code); |
1541 if (value != Heap::undefined_value()) return value; | 1566 if (value != Heap::undefined_value()) return value; |
1542 | 1567 |
1543 char buffer[1]; | 1568 char buffer[1]; |
1544 buffer[0] = static_cast<char>(code); | 1569 buffer[0] = static_cast<char>(code); |
1545 Object* result = LookupSymbol(Vector<const char>(buffer, 1)); | 1570 Object* result = LookupSymbol(Vector<const char>(buffer, 1)); |
1546 | 1571 |
1547 if (result->IsFailure()) return result; | 1572 if (result->IsFailure()) return result; |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 } | 2046 } |
2022 if (map == long_external_ascii_string_map()) { | 2047 if (map == long_external_ascii_string_map()) { |
2023 return long_external_ascii_string_map(); | 2048 return long_external_ascii_string_map(); |
2024 } | 2049 } |
2025 | 2050 |
2026 // No match found. | 2051 // No match found. |
2027 return NULL; | 2052 return NULL; |
2028 } | 2053 } |
2029 | 2054 |
2030 | 2055 |
2031 Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer, | 2056 Object* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer, |
2032 int chars, | 2057 int chars, |
2033 uint32_t length_field) { | 2058 uint32_t length_field) { |
2034 // Ensure the chars matches the number of characters in the buffer. | 2059 // Ensure the chars matches the number of characters in the buffer. |
2035 ASSERT(static_cast<unsigned>(chars) == buffer->Length()); | 2060 ASSERT(static_cast<unsigned>(chars) == buffer->Length()); |
2036 // Determine whether the string is ascii. | 2061 // Determine whether the string is ascii. |
2037 bool is_ascii = true; | 2062 bool is_ascii = true; |
2038 while (buffer->has_more()) { | 2063 while (buffer->has_more()) { |
2039 if (buffer->GetNext() > unibrow::Utf8::kMaxOneByteChar) is_ascii = false; | 2064 if (buffer->GetNext() > unibrow::Utf8::kMaxOneByteChar) is_ascii = false; |
2040 } | 2065 } |
2041 buffer->Rewind(); | 2066 buffer->Rewind(); |
2042 | 2067 |
2043 // Compute map and object size. | 2068 // Compute map and object size. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2079 ASSERT_EQ(size, answer->Size()); | 2104 ASSERT_EQ(size, answer->Size()); |
2080 | 2105 |
2081 // Fill in the characters. | 2106 // Fill in the characters. |
2082 for (int i = 0; i < chars; i++) { | 2107 for (int i = 0; i < chars; i++) { |
2083 answer->Set(answer_shape, i, buffer->GetNext()); | 2108 answer->Set(answer_shape, i, buffer->GetNext()); |
2084 } | 2109 } |
2085 return answer; | 2110 return answer; |
2086 } | 2111 } |
2087 | 2112 |
2088 | 2113 |
| 2114 // External string resource that only contains a length field. These |
| 2115 // are used temporarily when allocating external symbols. |
| 2116 class DummyExternalStringResource |
| 2117 : public v8::String::ExternalStringResource { |
| 2118 public: |
| 2119 explicit DummyExternalStringResource(size_t length) : length_(length) { } |
| 2120 |
| 2121 virtual const uint16_t* data() const { |
| 2122 UNREACHABLE(); |
| 2123 return NULL; |
| 2124 } |
| 2125 |
| 2126 virtual size_t length() const { return length_; } |
| 2127 private: |
| 2128 size_t length_; |
| 2129 }; |
| 2130 |
| 2131 |
| 2132 Object* Heap::AllocateExternalSymbol(Vector<const char> string, int chars) { |
| 2133 // Attempt to allocate the resulting external string first. Use a |
| 2134 // dummy string resource that has the correct length so that we only |
| 2135 // have to patch the external string resource after the callback. |
| 2136 DummyExternalStringResource dummy_resource(chars); |
| 2137 Object* obj = AllocateExternalSymbolFromTwoByte(&dummy_resource); |
| 2138 if (obj->IsFailure()) return obj; |
| 2139 // Perform callback. |
| 2140 v8::String::ExternalStringResource* resource = |
| 2141 global_external_symbol_callback_(string.start(), string.length()); |
| 2142 // Patch the resource pointer of the result. |
| 2143 ExternalTwoByteString* result = ExternalTwoByteString::cast(obj); |
| 2144 result->set_resource(resource); |
| 2145 ASSERT(result->IsEqualTo(string)); |
| 2146 return result; |
| 2147 } |
| 2148 |
| 2149 |
2089 Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) { | 2150 Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) { |
2090 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 2151 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
2091 int size = SeqAsciiString::SizeFor(length); | 2152 int size = SeqAsciiString::SizeFor(length); |
2092 if (size > MaxHeapObjectSize()) { | 2153 if (size > MaxHeapObjectSize()) { |
2093 space = LO_SPACE; | 2154 space = LO_SPACE; |
2094 } | 2155 } |
2095 | 2156 |
2096 // Use AllocateRaw rather than Allocate because the object's size cannot be | 2157 // Use AllocateRaw rather than Allocate because the object's size cannot be |
2097 // determined from the map. | 2158 // determined from the map. |
2098 Object* result = AllocateRaw(size, space, OLD_DATA_SPACE); | 2159 Object* result = AllocateRaw(size, space, OLD_DATA_SPACE); |
(...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3251 #ifdef DEBUG | 3312 #ifdef DEBUG |
3252 bool Heap::GarbageCollectionGreedyCheck() { | 3313 bool Heap::GarbageCollectionGreedyCheck() { |
3253 ASSERT(FLAG_gc_greedy); | 3314 ASSERT(FLAG_gc_greedy); |
3254 if (Bootstrapper::IsActive()) return true; | 3315 if (Bootstrapper::IsActive()) return true; |
3255 if (disallow_allocation_failure()) return true; | 3316 if (disallow_allocation_failure()) return true; |
3256 return CollectGarbage(0, NEW_SPACE); | 3317 return CollectGarbage(0, NEW_SPACE); |
3257 } | 3318 } |
3258 #endif | 3319 #endif |
3259 | 3320 |
3260 } } // namespace v8::internal | 3321 } } // namespace v8::internal |
OLD | NEW |