Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 79eaa61a250e04e59abe087ae93fef6431519363..947a6e076f4b4deb1269c8a8dc703168b20ccae9 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -2512,7 +2512,7 @@ |
Heap* heap = GetHeap(); |
bool is_one_byte = this->IsOneByteRepresentation(); |
bool is_internalized = this->IsInternalizedString(); |
- bool has_pointers = StringShape(this).IsIndirect(); |
+ bool has_pointers = this->IsConsString() || this->IsSlicedString(); |
// Morph the string to an external string by replacing the map and |
// reinitializing the fields. This won't work if the space the existing |
@@ -2584,7 +2584,7 @@ |
if (size < ExternalString::kShortSize) return false; |
Heap* heap = GetHeap(); |
bool is_internalized = this->IsInternalizedString(); |
- bool has_pointers = StringShape(this).IsIndirect(); |
+ bool has_pointers = this->IsConsString() || this->IsSlicedString(); |
// Morph the string to an external string by replacing the map and |
// reinitializing the fields. This won't work if the space the existing |
@@ -10928,7 +10928,11 @@ |
return isolate->factory()->NewSubString(string, left, right); |
} |
-bool String::LooksValid() { return GetIsolate()->heap()->Contains(this); } |
+bool String::LooksValid() { |
+ if (!GetIsolate()->heap()->Contains(this)) return false; |
+ return true; |
+} |
+ |
// static |
MaybeHandle<String> Name::ToFunctionName(Handle<Name> name) { |
@@ -11062,20 +11066,14 @@ |
} |
string = cons->first(); |
shape = StringShape(string); |
- } else if (shape.representation_tag() == kSlicedStringTag) { |
+ } |
+ if (shape.representation_tag() == kSlicedStringTag) { |
SlicedString* slice = SlicedString::cast(string); |
offset = slice->offset(); |
string = slice->parent(); |
shape = StringShape(string); |
DCHECK(shape.representation_tag() != kConsStringTag && |
shape.representation_tag() != kSlicedStringTag); |
- } |
- if (shape.representation_tag() == kThinStringTag) { |
- ThinString* thin = ThinString::cast(string); |
- string = thin->actual(); |
- shape = StringShape(string); |
- DCHECK(!shape.IsCons()); |
- DCHECK(!shape.IsSliced()); |
} |
if (shape.encoding_tag() == kOneByteStringTag) { |
const uint8_t* start; |
@@ -11162,7 +11160,6 @@ |
return slice->parent()->GetTwoByteData(start + slice->offset()); |
} |
case kConsStringTag: |
- case kThinStringTag: |
UNREACHABLE(); |
return NULL; |
} |
@@ -11429,7 +11426,6 @@ |
return 0; |
} |
-uint16_t ThinString::ThinStringGet(int index) { return actual()->Get(index); } |
uint16_t SlicedString::SlicedStringGet(int index) { |
return parent()->Get(offset() + index); |
@@ -11524,10 +11520,6 @@ |
WriteToFlat(slice->parent(), sink, from + offset, to + offset); |
return; |
} |
- case kOneByteStringTag | kThinStringTag: |
- case kTwoByteStringTag | kThinStringTag: |
- source = ThinString::cast(source)->actual(); |
- break; |
} |
} |
} |
@@ -11749,17 +11741,6 @@ |
if (len != other->length()) return false; |
if (len == 0) return true; |
- // Fast check: if at least one ThinString is involved, dereference it/them |
- // and restart. |
- if (this->IsThinString() || other->IsThinString()) { |
- if (other->IsThinString()) other = ThinString::cast(other)->actual(); |
- if (this->IsThinString()) { |
- return ThinString::cast(this)->actual()->Equals(other); |
- } else { |
- return this->Equals(other); |
- } |
- } |
- |
// Fast check: if hash code is computed for both strings |
// a fast negative check can be performed. |
if (HasHashCode() && other->HasHashCode()) { |
@@ -11800,14 +11781,6 @@ |
int one_length = one->length(); |
if (one_length != two->length()) return false; |
if (one_length == 0) return true; |
- |
- // Fast check: if at least one ThinString is involved, dereference it/them |
- // and restart. |
- if (one->IsThinString() || two->IsThinString()) { |
- if (one->IsThinString()) one = handle(ThinString::cast(*one)->actual()); |
- if (two->IsThinString()) two = handle(ThinString::cast(*two)->actual()); |
- return String::Equals(one, two); |
- } |
// Fast check: if hash code is computed for both strings |
// a fast negative check can be performed. |
@@ -16864,14 +16837,6 @@ |
DCHECK(string_->IsInternalizedString()); |
return string_; |
} |
- // External strings get special treatment, to avoid copying their contents. |
- if (string_->IsExternalOneByteString()) { |
- return isolate->factory() |
- ->InternalizeExternalString<ExternalOneByteString>(string_); |
- } else if (string_->IsExternalTwoByteString()) { |
- return isolate->factory() |
- ->InternalizeExternalString<ExternalTwoByteString>(string_); |
- } |
// Otherwise allocate a new internalized string. |
return isolate->factory()->NewInternalizedStringImpl( |
string_, string_->length(), string_->hash_field()); |
@@ -16881,7 +16846,6 @@ |
return String::cast(obj)->Hash(); |
} |
- private: |
Handle<String> string_; |
}; |
@@ -17816,9 +17780,6 @@ |
if (string->IsInternalizedString()) { |
return string; |
} |
- if (string->IsThinString()) { |
- return handle(Handle<ThinString>::cast(string)->actual(), isolate); |
- } |
return LookupStringIfExists(isolate, string); |
} |
@@ -17865,72 +17826,31 @@ |
isolate->heap()->SetRootStringTable(*table); |
} |
-namespace { |
- |
-template <class StringClass> |
-void MigrateExternalStringResource(Isolate* isolate, Handle<String> from, |
- Handle<String> to) { |
- Handle<StringClass> cast_from = Handle<StringClass>::cast(from); |
- Handle<StringClass> cast_to = Handle<StringClass>::cast(to); |
- const typename StringClass::Resource* to_resource = cast_to->resource(); |
- if (to_resource == nullptr) { |
- // |to| is a just-created internalized copy of |from|. Migrate the resource. |
- cast_to->set_resource(cast_from->resource()); |
- // Zap |from|'s resource pointer to reflect the fact that |from| has |
- // relinquished ownership of its resource. |
- cast_from->set_resource(nullptr); |
- } else if (to_resource != cast_from->resource()) { |
- // |to| already existed and has its own resource. Finalize |from|. |
- isolate->heap()->FinalizeExternalString(*from); |
- } |
-} |
- |
-} // namespace |
Handle<String> StringTable::LookupString(Isolate* isolate, |
Handle<String> string) { |
- if (string->IsThinString()) { |
- DCHECK(Handle<ThinString>::cast(string)->actual()->IsInternalizedString()); |
- return handle(Handle<ThinString>::cast(string)->actual(), isolate); |
- } |
if (string->IsConsString() && string->IsFlat()) { |
- string = handle(Handle<ConsString>::cast(string)->first(), isolate); |
+ string = String::Flatten(string); |
if (string->IsInternalizedString()) return string; |
} |
InternalizedStringKey key(string); |
Handle<String> result = LookupKey(isolate, &key); |
- if (string->IsExternalString()) { |
- if (result->IsExternalOneByteString()) { |
- MigrateExternalStringResource<ExternalOneByteString>(isolate, string, |
- result); |
- } else if (result->IsExternalTwoByteString()) { |
- MigrateExternalStringResource<ExternalTwoByteString>(isolate, string, |
- result); |
- } |
- } |
- |
- // The LookupKey() call above tries to internalize the string in-place. |
- // In cases where that wasn't possible (e.g. new-space strings), turn them |
- // into ThinStrings referring to their internalized versions now. |
- if (!string->IsInternalizedString()) { |
+ if (string->IsConsString()) { |
+ Handle<ConsString> cons = Handle<ConsString>::cast(string); |
+ cons->set_first(*result); |
+ cons->set_second(isolate->heap()->empty_string()); |
+ } else if (string->IsSlicedString()) { |
+ STATIC_ASSERT(ConsString::kSize == SlicedString::kSize); |
DisallowHeapAllocation no_gc; |
bool one_byte = result->IsOneByteRepresentation(); |
- Handle<Map> map = one_byte ? isolate->factory()->thin_one_byte_string_map() |
- : isolate->factory()->thin_string_map(); |
- int old_size = string->Size(); |
- DCHECK(old_size >= ThinString::kSize); |
- string->synchronized_set_map(*map); |
- Handle<ThinString> thin = Handle<ThinString>::cast(string); |
- thin->set_actual(*result); |
- Address thin_end = thin->address() + ThinString::kSize; |
- int size_delta = old_size - ThinString::kSize; |
- if (size_delta != 0) { |
- Heap* heap = isolate->heap(); |
- heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo); |
- heap->AdjustLiveBytes(*thin, -size_delta); |
- } |
+ Handle<Map> map = one_byte ? isolate->factory()->cons_one_byte_string_map() |
+ : isolate->factory()->cons_string_map(); |
+ string->set_map(*map); |
+ Handle<ConsString> cons = Handle<ConsString>::cast(string); |
+ cons->set_first(*result); |
+ cons->set_second(isolate->heap()->empty_string()); |
} |
return result; |
} |