Reviewers: mvstanton,
Description:
Correctly hook up back references to internalized strings in code
deserializer.
[email protected]
Please review this at https://codereview.chromium.org/411483002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+54, -7 lines):
M src/objects.h
M src/objects-inl.h
M src/serialize.h
M src/serialize.cc
A + test/mjsunit/deserialize-reference.js
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
0aca5cfcdb488b0718af22d18c95afc69a17da19..4cbd65a4985d1811ff9d131436c6edae4119c694
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -6580,6 +6580,30 @@ bool String::AsArrayIndex(uint32_t* index) {
}
+void String::SetForwardedInternalizedString(String* canonical) {
+ ASSERT(IsInternalizedString());
+ ASSERT(canonical->IsInternalizedString());
+ ASSERT(SlowEquals(canonical));
+ ASSERT(HasHashCode());
+ ASSERT(canonical->HasHashCode());
+ WRITE_FIELD(this, kHashFieldOffset, canonical);
+ // With canonical being a string, the LSB is set. Interpreted as hash
code,
+ // this means that the hash code uninitialized. We use this for
distinction.
+ ASSERT(!HasHashCode());
+}
+
+
+String* String::GetForwardedInternalizedString() {
+ ASSERT(IsInternalizedString());
+ if (HasHashCode()) return this;
+ String* canonical = String::cast(READ_FIELD(this, kHashFieldOffset));
+ ASSERT(canonical->IsInternalizedString());
+ ASSERT(SlowEquals(canonical));
+ ASSERT(canonical->HasHashCode());
+ return canonical;
+}
+
+
Object* JSReceiver::GetConstructor() {
return map()->constructor();
}
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
e7f5a598d99be6c65283da8067b9152db35f333e..b049dbf8c094b109a422a37e5b3825ab584d36c7
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -9325,6 +9325,11 @@ class String: public Name {
static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
bool include_ending_line);
+ // Use the hash field to forward to the canonical internalized string
+ // when deserializing an internalized string.
+ inline void SetForwardedInternalizedString(String* string);
+ inline String* GetForwardedInternalizedString();
+
private:
friend class Name;
friend class StringTableInsertionKey;
Index: src/serialize.cc
diff --git a/src/serialize.cc b/src/serialize.cc
index
c35464e2f8e37954f753e7129ac61e82349fd1e2..08c9cd145983305f17a1b9e989e4a2bfe04fe93b
100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -867,7 +867,7 @@ class StringTableInsertionKey : public HashTableKey {
};
-HeapObject* Deserializer::ProcessObjectFromSerializedCode(HeapObject* obj)
{
+HeapObject* Deserializer::ProcessNewObjectFromSerializedCode(HeapObject*
obj) {
if (obj->IsString()) {
String* string = String::cast(obj);
// Uninitialize hash field as the hash seed may have changed.
@@ -876,13 +876,23 @@ HeapObject*
Deserializer::ProcessObjectFromSerializedCode(HeapObject* obj) {
DisallowHeapAllocation no_gc;
HandleScope scope(isolate_);
StringTableInsertionKey key(string);
- return *StringTable::LookupKey(isolate_, &key);
+ String* canonical = *StringTable::LookupKey(isolate_, &key);
+ string->SetForwardedInternalizedString(canonical);
+ return canonical;
}
}
return obj;
}
+Object* Deserializer::ProcessBackRefInSerializedCode(Object* obj) {
+ if (obj->IsInternalizedString()) {
+ return String::cast(obj)->GetForwardedInternalizedString();
+ }
+ 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
@@ -907,7 +917,7 @@ void Deserializer::ReadObject(int space_number,
if (obj->IsAllocationSite())
RelinkAllocationSite(AllocationSite::cast(obj));
// Fix up strings from serialized user code.
- if (deserializing_user_code()) obj =
ProcessObjectFromSerializedCode(obj);
+ if (deserializing_user_code()) obj =
ProcessNewObjectFromSerializedCode(obj);
*write_back = obj;
#ifdef DEBUG
@@ -972,6 +982,9 @@ void Deserializer::ReadChunk(Object** current,
} else if (where == kBackref)
{ \
emit_write_barrier = (space_number ==
NEW_SPACE); \
new_object = GetAddressFromEnd(data &
kSpaceMask); \
+ if (deserializing_user_code())
{ \
+ new_object =
ProcessBackRefInSerializedCode(new_object); \
+
} \
} else if (where == kBuiltin)
{ \
ASSERT(deserializing_user_code()); \
int builtin_id =
source_->GetInt(); \
@@ -992,6 +1005,9 @@ void Deserializer::ReadChunk(Object** current,
reinterpret_cast<Address>(current) +
skip); \
emit_write_barrier = (space_number ==
NEW_SPACE); \
new_object = GetAddressFromEnd(data &
kSpaceMask); \
+ if (deserializing_user_code())
{ \
+ new_object =
ProcessBackRefInSerializedCode(new_object); \
+
} \
} \
if (within == kInnerPointer)
{ \
if (space_number != CODE_SPACE || new_object->IsCode())
{ \
Index: src/serialize.h
diff --git a/src/serialize.h b/src/serialize.h
index
0676c39ed139ded0ff490378c584a35404341356..c9805678e274a8dd230529b5693fbd4cbcddaf4c
100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -280,7 +280,9 @@ class Deserializer: public SerializerDeserializer {
Object** start, Object** end, int space, Address object_address);
void ReadObject(int space_number, Object** write_back);
- HeapObject* ProcessObjectFromSerializedCode(HeapObject* obj);
+ // Special handling for serialized code like hooking up internalized
strings.
+ HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj);
+ Object* ProcessBackRefInSerializedCode(Object* obj);
// This routine both allocates a new object, and also keeps
// track of where objects have been allocated so that we can
Index: test/mjsunit/deserialize-reference.js
diff --git a/test/mjsunit/regress/regress-debug-context-load.js
b/test/mjsunit/deserialize-reference.js
similarity index 67%
copy from test/mjsunit/regress/regress-debug-context-load.js
copy to test/mjsunit/deserialize-reference.js
index
0b3c275f99b016825cd563a700772bbddb7e4bad..b03201315932eab59e38c135d219192e6dcdf0eb
100644
--- a/test/mjsunit/regress/regress-debug-context-load.js
+++ b/test/mjsunit/deserialize-reference.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --expose-debug-as debug
+// Flags: --cache=code --serialize-toplevel
-Debug = debug.Debug;
-Debug.setListener(null);
+var a = "123";
+assertEquals(a, "123");
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.