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

Unified Diff: src/objects.cc

Issue 21117: Allow the morphing of strings to external strings to avoid having to... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698