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

Unified Diff: src/serialize.cc

Issue 387343002: Fix up internalized strings after deserializing user code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: remove TODO Created 6 years, 5 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
Index: src/serialize.cc
diff --git a/src/serialize.cc b/src/serialize.cc
index 89ba1be099afc6d9a295907b54d002c7711fa5f6..fe84894ef6f780dd7c2211e4483db5050692aa96 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -718,6 +718,7 @@ class CodeAddressMap: public CodeEventLogger {
Deserializer::Deserializer(SnapshotByteSource* source)
: isolate_(NULL),
+ deserialize_code_(false),
source_(source),
external_reference_decoder_(NULL) {
for (int i = 0; i < LAST_SPACE + 1; i++) {
@@ -832,6 +833,54 @@ void Deserializer::RelinkAllocationSite(AllocationSite* site) {
}
+// Used to insert a deserialized internalized string into the string table.
+class StringTableInsertionKey : public HashTableKey {
+ public:
+ explicit StringTableInsertionKey(String* string)
+ : string_(string), hash_(HashForObject(string)) {
+ ASSERT(string->IsInternalizedString());
+ }
+
+ virtual bool IsMatch(Object* string) {
+ // We know that all entries in a hash table had their hash keys created.
+ // Use that knowledge to have fast failure.
+ if (hash_ != HashForObject(string)) return false;
+ // We want to compare the content of two internalized strings here.
+ return string_->SlowEquals(String::cast(string));
+ }
+
+ virtual uint32_t Hash() V8_OVERRIDE { return hash_; }
+
+ virtual uint32_t HashForObject(Object* key) V8_OVERRIDE {
+ return String::cast(key)->Hash();
+ }
+
+ MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate)
+ V8_OVERRIDE {
+ return handle(string_, isolate);
+ }
+
+ String* string_;
+ uint32_t hash_;
+};
+
+
+HeapObject* Deserializer::ProcessObjectFromSerializedCode(HeapObject* obj) {
+ if (obj->IsString()) {
+ String* string = String::cast(obj);
+ // Uninitialize hash field as the hash seed may have changed.
+ string->set_hash_field(String::kEmptyHashField);
+ if (string->IsInternalizedString()) {
+ DisallowHeapAllocation no_gc;
+ HandleScope scope(isolate_);
+ StringTableInsertionKey key(string);
+ return *StringTable::LookupKey(isolate_, &key);
+ }
+ }
+ return obj;
+}
+
+
// This routine writes the new object into the pointer provided and then
// returns true if the new object was in young space and false otherwise.
// The reason for this strange interface is that otherwise the object is
@@ -843,7 +892,6 @@ void Deserializer::ReadObject(int space_number,
Address address = Allocate(space_number, size);
HeapObject* obj = HeapObject::FromAddress(address);
isolate_->heap()->OnAllocationEvent(obj, size);
- *write_back = obj;
Object** current = reinterpret_cast<Object**>(address);
Object** limit = current + (size >> kPointerSizeLog2);
if (FLAG_log_snapshot_positions) {
@@ -854,10 +902,12 @@ void Deserializer::ReadObject(int space_number,
// TODO(mvstanton): consider treating the heap()->allocation_sites_list()
// as a (weak) root. If this root is relocated correctly,
// RelinkAllocationSite() isn't necessary.
- if (obj->IsAllocationSite()) {
- RelinkAllocationSite(AllocationSite::cast(obj));
- }
+ if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
+
+ // Fix up strings from serialized user code.
+ if (deserialize_code_) obj = ProcessObjectFromSerializedCode(obj);
+ *write_back = obj;
#ifdef DEBUG
bool is_codespace = (space_number == CODE_SPACE);
ASSERT(obj->IsCode() == is_codespace);
@@ -921,13 +971,13 @@ void Deserializer::ReadChunk(Object** current,
emit_write_barrier = (space_number == NEW_SPACE); \
new_object = GetAddressFromEnd(data & kSpaceMask); \
} else if (where == kBuiltin) { \
+ ASSERT(deserialize_code_); \
int builtin_id = source_->GetInt(); \
ASSERT_LE(0, builtin_id); \
ASSERT_LT(builtin_id, Builtins::builtin_count); \
Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
new_object = isolate->builtins()->builtin(name); \
emit_write_barrier = false; \
- PrintF("BUILTIN how within %d, %d\n", how, within); \
} else { \
ASSERT(where == kBackrefWithSkip); \
int skip = source_->GetInt(); \
@@ -1859,8 +1909,6 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
// TODO(yangguo) wire up stubs from stub cache.
// TODO(yangguo) wire up script source.
- // TODO(yangguo) wire up internalized strings
- ASSERT(!heap_object->IsInternalizedString());
// TODO(yangguo) We cannot deal with different hash seeds yet.
ASSERT(!heap_object->IsHashTable());
@@ -1916,6 +1964,7 @@ Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) {
SerializedCodeData scd(data);
SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
Deserializer deserializer(&payload);
+ deserializer.ExpectSerializedCode();
STATIC_ASSERT(NEW_SPACE == 0);
// TODO(yangguo) what happens if remaining new space is too small?
for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
« no previous file with comments | « src/serialize.h ('k') | test/cctest/test-serialize.cc » ('j') | test/cctest/test-serialize.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698