Index: src/objects.cc |
=================================================================== |
--- src/objects.cc (revision 1251) |
+++ src/objects.cc (working copy) |
@@ -667,6 +667,92 @@ |
} |
+bool String::MakeExternal(v8::String::ExternalStringResource* resource) { |
+#ifdef DEBUG |
+ { // NOLINT (presubmit.py gets confused about if and braces) |
+ // Assert that the resource and the string are equivalent. |
+ ASSERT(static_cast<size_t>(this->length()) == resource->length()); |
+ SmartPointer<uc16> smart_chars = this->ToWideCString(); |
+ ASSERT(memcmp(*smart_chars, |
+ resource->data(), |
+ resource->length()*sizeof(**smart_chars)) == 0); |
+ } |
+#endif // DEBUG |
+ |
+ int size = this->Size(); // Byte size of the original string. |
+ if (size < ExternalString::kSize) { |
+ // The string is too small to fit an external String in its place. This can |
+ // only happen for zero length strings. |
+ return false; |
+ } |
+ ASSERT(size >= ExternalString::kSize); |
+ bool is_symbol = this->IsSymbol(); |
+ int length = this->length(); |
+ |
+ // Morph the object to an external string by adjusting the map and |
+ // reinitializing the fields. |
+ this->set_map(ExternalTwoByteString::StringMap(length)); |
+ ExternalTwoByteString* self = ExternalTwoByteString::cast(this); |
+ self->set_length(length); |
+ self->set_resource(resource); |
+ // Additionally make the object into an external symbol if the original string |
+ // was a symbol to start with. |
+ if (is_symbol) { |
+ self->Hash(); // Force regeneration of the hash value. |
+ // Now morph this external string into a external symbol. |
+ self->set_map(ExternalTwoByteString::SymbolMap(length)); |
+ } |
+ |
+ // Fill the remainder of the string with dead wood. |
+ int new_size = this->Size(); // Byte size of the external String object. |
+ Heap::CreateFillerObjectAt(this->address() + new_size, size - new_size); |
+ return true; |
+} |
+ |
+ |
+bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { |
+#ifdef DEBUG |
+ { // NOLINT (presubmit.py gets confused about if and braces) |
+ // Assert that the resource and the string are equivalent. |
+ ASSERT(static_cast<size_t>(this->length()) == resource->length()); |
+ SmartPointer<char> smart_chars = this->ToCString(); |
+ ASSERT(memcmp(*smart_chars, |
+ resource->data(), |
+ resource->length()*sizeof(**smart_chars)) == 0); |
+ } |
+#endif // DEBUG |
+ |
+ int size = this->Size(); // Byte size of the original string. |
+ if (size < ExternalString::kSize) { |
+ // The string is too small to fit an external String in its place. This can |
+ // only happen for zero length strings. |
+ return false; |
+ } |
+ ASSERT(size >= ExternalString::kSize); |
+ bool is_symbol = this->IsSymbol(); |
+ int length = this->length(); |
+ |
+ // Morph the object to an external string by adjusting the map and |
+ // reinitializing the fields. |
+ this->set_map(ExternalAsciiString::StringMap(length)); |
+ ExternalAsciiString* self = ExternalAsciiString::cast(this); |
+ self->set_length(length); |
+ self->set_resource(resource); |
+ // Additionally make the object into an external symbol if the original string |
+ // was a symbol to start with. |
+ if (is_symbol) { |
+ self->Hash(); // Force regeneration of the hash value. |
+ // Now morph this external string into a external symbol. |
+ self->set_map(ExternalAsciiString::SymbolMap(length)); |
+ } |
+ |
+ // Fill the remainder of the string with dead wood. |
+ int new_size = this->Size(); // Byte size of the external String object. |
+ Heap::CreateFillerObjectAt(this->address() + new_size, size - new_size); |
+ return true; |
+} |
+ |
+ |
void String::StringShortPrint(StringStream* accumulator) { |
StringShape shape(this); |
int len = length(shape); |
@@ -1927,23 +2013,15 @@ |
if (obj->IsFailure()) return obj; |
Map* new_map = Map::cast(obj); |
- // Clear inobject properties if needed by adjusting the instance |
- // size and putting in a filler or byte array instead of the |
- // inobject properties. |
+ // Clear inobject properties if needed by adjusting the instance size and |
+ // putting in a filler object instead of the inobject properties. |
if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) { |
int instance_size_delta = map()->inobject_properties() * kPointerSize; |
int new_instance_size = map()->instance_size() - instance_size_delta; |
new_map->set_inobject_properties(0); |
new_map->set_instance_size(new_instance_size); |
- if (instance_size_delta == kPointerSize) { |
- WRITE_FIELD(this, new_instance_size, Heap::one_word_filler_map()); |
- } else { |
- int byte_array_length = ByteArray::LengthFor(instance_size_delta); |
- int byte_array_length_offset = new_instance_size + kPointerSize; |
- WRITE_FIELD(this, new_instance_size, Heap::byte_array_map()); |
- WRITE_INT_FIELD(this, byte_array_length_offset, byte_array_length); |
- } |
- WRITE_BARRIER(this, new_instance_size); |
+ Heap::CreateFillerObjectAt(this->address() + new_instance_size, |
+ instance_size_delta); |
} |
new_map->set_unused_property_fields(0); |