summaryrefslogtreecommitdiff
path: root/deps/v8/src/heap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/heap.cc')
-rw-r--r--deps/v8/src/heap.cc158
1 files changed, 62 insertions, 96 deletions
diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc
index ae18fbe6b7..43886c144c 100644
--- a/deps/v8/src/heap.cc
+++ b/deps/v8/src/heap.cc
@@ -733,10 +733,7 @@ void Heap::Scavenge() {
ScavengeVisitor scavenge_visitor;
// Copy roots.
- IterateRoots(&scavenge_visitor);
-
- // Copy objects reachable from weak pointers.
- GlobalHandles::IterateWeakRoots(&scavenge_visitor);
+ IterateRoots(&scavenge_visitor, VISIT_ALL);
// Copy objects reachable from the old generation. By definition,
// there are no intergenerational pointers in code or data spaces.
@@ -1730,6 +1727,7 @@ Object* Heap::AllocateProxy(Address proxy, PretenureFlag pretenure) {
// Statically ensure that it is safe to allocate proxies in paged spaces.
STATIC_ASSERT(Proxy::kSize <= Page::kMaxHeapObjectSize);
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
+ if (always_allocate()) space = OLD_DATA_SPACE;
Object* result = Allocate(proxy_map(), space);
if (result->IsFailure()) return result;
@@ -1766,10 +1764,14 @@ Object* Heap::AllocateSharedFunctionInfo(Object* name) {
Object* Heap::AllocateConsString(String* first, String* second) {
int first_length = first->length();
- if (first_length == 0) return second;
+ if (first_length == 0) {
+ return second;
+ }
int second_length = second->length();
- if (second_length == 0) return first;
+ if (second_length == 0) {
+ return first;
+ }
int length = first_length + second_length;
bool is_ascii = first->IsAsciiRepresentation()
@@ -1821,54 +1823,18 @@ Object* Heap::AllocateConsString(String* first, String* second) {
: long_cons_string_map();
}
- Object* result = Allocate(map, NEW_SPACE);
+ Object* result = Allocate(map,
+ always_allocate() ? OLD_POINTER_SPACE : NEW_SPACE);
if (result->IsFailure()) return result;
- ASSERT(InNewSpace(result));
ConsString* cons_string = ConsString::cast(result);
- cons_string->set_first(first, SKIP_WRITE_BARRIER);
- cons_string->set_second(second, SKIP_WRITE_BARRIER);
+ WriteBarrierMode mode = cons_string->GetWriteBarrierMode();
+ cons_string->set_first(first, mode);
+ cons_string->set_second(second, mode);
cons_string->set_length(length);
return result;
}
-Object* Heap::AllocateSlicedString(String* buffer,
- int start,
- int end) {
- int length = end - start;
-
- // If the resulting string is small make a sub string.
- if (length <= String::kMinNonFlatLength) {
- return Heap::AllocateSubString(buffer, start, end);
- }
-
- Map* map;
- if (length <= String::kMaxShortSize) {
- map = buffer->IsAsciiRepresentation() ?
- short_sliced_ascii_string_map() :
- short_sliced_string_map();
- } else if (length <= String::kMaxMediumSize) {
- map = buffer->IsAsciiRepresentation() ?
- medium_sliced_ascii_string_map() :
- medium_sliced_string_map();
- } else {
- map = buffer->IsAsciiRepresentation() ?
- long_sliced_ascii_string_map() :
- long_sliced_string_map();
- }
-
- Object* result = Allocate(map, NEW_SPACE);
- if (result->IsFailure()) return result;
-
- SlicedString* sliced_string = SlicedString::cast(result);
- sliced_string->set_buffer(buffer);
- sliced_string->set_start(start);
- sliced_string->set_length(length);
-
- return result;
-}
-
-
Object* Heap::AllocateSubString(String* buffer,
int start,
int end) {
@@ -1888,22 +1854,19 @@ Object* Heap::AllocateSubString(String* buffer,
? AllocateRawAsciiString(length)
: AllocateRawTwoByteString(length);
if (result->IsFailure()) return result;
+ String* string_result = String::cast(result);
// Copy the characters into the new object.
- String* string_result = String::cast(result);
- StringHasher hasher(length);
- int i = 0;
- for (; i < length && hasher.is_array_index(); i++) {
- uc32 c = buffer->Get(start + i);
- hasher.AddCharacter(c);
- string_result->Set(i, c);
- }
- for (; i < length; i++) {
- uc32 c = buffer->Get(start + i);
- hasher.AddCharacterNoIndex(c);
- string_result->Set(i, c);
+ if (buffer->IsAsciiRepresentation()) {
+ ASSERT(string_result->IsAsciiRepresentation());
+ char* dest = SeqAsciiString::cast(string_result)->GetChars();
+ String::WriteToFlat(buffer, dest, start, end);
+ } else {
+ ASSERT(string_result->IsTwoByteRepresentation());
+ uc16* dest = SeqTwoByteString::cast(string_result)->GetChars();
+ String::WriteToFlat(buffer, dest, start, end);
}
- string_result->set_length_field(hasher.GetHashField());
+
return result;
}
@@ -1911,20 +1874,24 @@ Object* Heap::AllocateSubString(String* buffer,
Object* Heap::AllocateExternalStringFromAscii(
ExternalAsciiString::Resource* resource) {
Map* map;
- int length = resource->length();
- if (length <= String::kMaxShortSize) {
+ size_t length = resource->length();
+ if (length <= static_cast<size_t>(String::kMaxShortSize)) {
map = short_external_ascii_string_map();
- } else if (length <= String::kMaxMediumSize) {
+ } else if (length <= static_cast<size_t>(String::kMaxMediumSize)) {
map = medium_external_ascii_string_map();
- } else {
+ } else if (length <= static_cast<size_t>(String::kMaxLength)) {
map = long_external_ascii_string_map();
+ } else {
+ Top::context()->mark_out_of_memory();
+ return Failure::OutOfMemoryException();
}
- Object* result = Allocate(map, NEW_SPACE);
+ Object* result = Allocate(map,
+ always_allocate() ? OLD_DATA_SPACE : NEW_SPACE);
if (result->IsFailure()) return result;
ExternalAsciiString* external_string = ExternalAsciiString::cast(result);
- external_string->set_length(length);
+ external_string->set_length(static_cast<int>(length));
external_string->set_resource(resource);
return result;
@@ -1933,14 +1900,18 @@ Object* Heap::AllocateExternalStringFromAscii(
Object* Heap::AllocateExternalStringFromTwoByte(
ExternalTwoByteString::Resource* resource) {
- int length = resource->length();
-
- Map* map = ExternalTwoByteString::StringMap(length);
- Object* result = Allocate(map, NEW_SPACE);
+ size_t length = resource->length();
+ if (length > static_cast<size_t>(String::kMaxLength)) {
+ Top::context()->mark_out_of_memory();
+ return Failure::OutOfMemoryException();
+ }
+ Map* map = ExternalTwoByteString::StringMap(static_cast<int>(length));
+ Object* result = Allocate(map,
+ always_allocate() ? OLD_DATA_SPACE : NEW_SPACE);
if (result->IsFailure()) return result;
ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result);
- external_string->set_length(length);
+ external_string->set_length(static_cast<int>(length));
external_string->set_resource(resource);
return result;
@@ -2321,6 +2292,7 @@ Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) {
AllocationSpace space =
(pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
if (map->instance_size() > MaxObjectSizeInPagedSpace()) space = LO_SPACE;
+ if (always_allocate()) space = OLD_POINTER_SPACE;
Object* obj = Allocate(map, space);
if (obj->IsFailure()) return obj;
@@ -2603,20 +2575,6 @@ Map* Heap::SymbolMapForString(String* string) {
return long_cons_ascii_symbol_map();
}
- if (map == short_sliced_string_map()) return short_sliced_symbol_map();
- if (map == medium_sliced_string_map()) return medium_sliced_symbol_map();
- if (map == long_sliced_string_map()) return long_sliced_symbol_map();
-
- if (map == short_sliced_ascii_string_map()) {
- return short_sliced_ascii_symbol_map();
- }
- if (map == medium_sliced_ascii_string_map()) {
- return medium_sliced_ascii_symbol_map();
- }
- if (map == long_sliced_ascii_string_map()) {
- return long_sliced_ascii_symbol_map();
- }
-
if (map == short_external_string_map()) {
return short_external_symbol_map();
}
@@ -3117,7 +3075,7 @@ void Heap::Verify() {
ASSERT(HasBeenSetup());
VerifyPointersVisitor visitor;
- IterateRoots(&visitor);
+ IterateRoots(&visitor, VISIT_ONLY_STRONG);
new_space_.Verify();
@@ -3244,14 +3202,14 @@ void Heap::IterateRSet(PagedSpace* space, ObjectSlotCallback copy_object_func) {
}
-void Heap::IterateRoots(ObjectVisitor* v) {
- IterateStrongRoots(v);
+void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
+ IterateStrongRoots(v, mode);
v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex]));
v->Synchronize("symbol_table");
}
-void Heap::IterateStrongRoots(ObjectVisitor* v) {
+void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
v->Synchronize("strong_root_list");
@@ -3284,7 +3242,11 @@ void Heap::IterateStrongRoots(ObjectVisitor* v) {
v->Synchronize("builtins");
// Iterate over global handles.
- GlobalHandles::IterateRoots(v);
+ if (mode == VISIT_ONLY_STRONG) {
+ GlobalHandles::IterateStrongRoots(v);
+ } else {
+ GlobalHandles::IterateAllRoots(v);
+ }
v->Synchronize("globalhandles");
// Iterate over pointers being held by inactive threads.
@@ -3455,14 +3417,18 @@ bool Heap::Setup(bool create_heap_objects) {
}
-void Heap::SetStackLimit(intptr_t limit) {
+void Heap::SetStackLimits() {
// On 64 bit machines, pointers are generally out of range of Smis. We write
// something that looks like an out of range Smi to the GC.
- // Set up the special root array entry containing the stack guard.
- // This is actually an address, but the tag makes the GC ignore it.
+ // Set up the special root array entries containing the stack limits.
+ // These are actually addresses, but the tag makes the GC ignore it.
roots_[kStackLimitRootIndex] =
- reinterpret_cast<Object*>((limit & ~kSmiTagMask) | kSmiTag);
+ reinterpret_cast<Object*>(
+ (StackGuard::jslimit() & ~kSmiTagMask) | kSmiTag);
+ roots_[kRealStackLimitRootIndex] =
+ reinterpret_cast<Object*>(
+ (StackGuard::real_jslimit() & ~kSmiTagMask) | kSmiTag);
}
@@ -3889,7 +3855,7 @@ void Heap::TracePathToObject() {
search_for_any_global = false;
MarkRootVisitor root_visitor;
- IterateRoots(&root_visitor);
+ IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
}
@@ -3901,7 +3867,7 @@ void Heap::TracePathToGlobal() {
search_for_any_global = true;
MarkRootVisitor root_visitor;
- IterateRoots(&root_visitor);
+ IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
}
#endif