Commit 1e44e90e authored by jgruber's avatar jgruber Committed by Commit Bot

[snapshot] Convert CASE_BODY macro to function

The CASE_BODY macro is inconvenient for debugging, as gdb points only at
the SINGLE_CASE line, not the actual expanded line.

Converting it into a templatized function should preserve optimization
opportunities for the compiler while making debugging much easier.

Bug: v8:6624
Change-Id: I864eff190e39e3230c529ced5c4919aa875763b1
Reviewed-on: https://chromium-review.googlesource.com/612084
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47471}
parent 0d14ae17
......@@ -385,97 +385,10 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \
STATIC_ASSERT((space_number & ~kSpaceMask) == 0);
#define CASE_BODY(where, how, within, space_number_if_any) \
{ \
bool emit_write_barrier = false; \
bool current_was_incremented = false; \
int space_number = space_number_if_any == kAnyOldSpace \
? (data & kSpaceMask) \
: space_number_if_any; \
if (where == kNewObject && how == kPlain && within == kStartOfObject) { \
ReadObject(space_number, current); \
emit_write_barrier = (space_number == NEW_SPACE); \
} else { \
Object* new_object = NULL; /* May not be a real Object pointer. */ \
if (where == kNewObject) { \
ReadObject(space_number, &new_object); \
} else if (where == kBackref) { \
emit_write_barrier = (space_number == NEW_SPACE); \
new_object = GetBackReferencedObject(data & kSpaceMask); \
} else if (where == kBackrefWithSkip) { \
int skip = source_.GetInt(); \
current = reinterpret_cast<Object**>( \
reinterpret_cast<Address>(current) + skip); \
emit_write_barrier = (space_number == NEW_SPACE); \
new_object = GetBackReferencedObject(data & kSpaceMask); \
} else if (where == kRootArray) { \
int id = source_.GetInt(); \
Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(id); \
new_object = isolate->heap()->root(root_index); \
emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
hot_objects_.Add(HeapObject::cast(new_object)); \
} else if (where == kPartialSnapshotCache) { \
int cache_index = source_.GetInt(); \
new_object = isolate->partial_snapshot_cache()->at(cache_index); \
emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
} else if (where == kExternalReference) { \
int skip = source_.GetInt(); \
current = reinterpret_cast<Object**>( \
reinterpret_cast<Address>(current) + skip); \
uint32_t reference_id = static_cast<uint32_t>(source_.GetInt()); \
Address address = external_reference_table_->address(reference_id); \
new_object = reinterpret_cast<Object*>(address); \
} else if (where == kAttachedReference) { \
int index = source_.GetInt(); \
new_object = *attached_objects_[index]; \
emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
} else { \
DCHECK(where == kBuiltin); \
DCHECK(deserializing_user_code()); \
int builtin_id = source_.GetInt(); \
DCHECK_LE(0, builtin_id); \
DCHECK_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; \
} \
if (within == kInnerPointer) { \
DCHECK(how == kFromCode); \
if (new_object->IsCode()) { \
Code* new_code_object = Code::cast(new_object); \
new_object = \
reinterpret_cast<Object*>(new_code_object->instruction_start()); \
} else { \
Cell* cell = Cell::cast(new_object); \
new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \
} \
} \
if (how == kFromCode) { \
Address location_of_branch_data = reinterpret_cast<Address>(current); \
Assembler::deserialization_set_special_target_at( \
isolate, location_of_branch_data, \
Code::cast(HeapObject::FromAddress(current_object_address)), \
reinterpret_cast<Address>(new_object)); \
location_of_branch_data += Assembler::kSpecialTargetSize; \
current = reinterpret_cast<Object**>(location_of_branch_data); \
current_was_incremented = true; \
} else { \
UnalignedCopy(current, &new_object); \
} \
} \
if (emit_write_barrier && write_barrier_needed) { \
Address current_address = reinterpret_cast<Address>(current); \
SLOW_DCHECK(isolate->heap()->ContainsSlow(current_object_address)); \
isolate->heap()->RecordWrite( \
HeapObject::FromAddress(current_object_address), \
reinterpret_cast<Object**>(current_address), \
*reinterpret_cast<Object**>(current_address)); \
} \
if (!current_was_incremented) { \
current++; \
} \
break; \
}
#define CASE_BODY(where, how, within, space_number_if_any) \
current = ReadDataCase<where, how, within, space_number_if_any>( \
isolate, current, current_object_address, data, write_barrier_needed); \
break;
// This generates a case and a body for the new space (which has to do extra
// write barrier handling) and handles the other spaces with fall-through cases
......@@ -760,5 +673,100 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
CHECK_EQ(limit, current);
return true;
}
template <int where, int how, int within, int space_number_if_any>
Object** Deserializer::ReadDataCase(Isolate* isolate, Object** current,
Address current_object_address, byte data,
bool write_barrier_needed) {
bool emit_write_barrier = false;
bool current_was_incremented = false;
int space_number = space_number_if_any == kAnyOldSpace ? (data & kSpaceMask)
: space_number_if_any;
if (where == kNewObject && how == kPlain && within == kStartOfObject) {
ReadObject(space_number, current);
emit_write_barrier = (space_number == NEW_SPACE);
} else {
Object* new_object = NULL; /* May not be a real Object pointer. */
if (where == kNewObject) {
ReadObject(space_number, &new_object);
} else if (where == kBackref) {
emit_write_barrier = (space_number == NEW_SPACE);
new_object = GetBackReferencedObject(data & kSpaceMask);
} else if (where == kBackrefWithSkip) {
int skip = source_.GetInt();
current =
reinterpret_cast<Object**>(reinterpret_cast<Address>(current) + skip);
emit_write_barrier = (space_number == NEW_SPACE);
new_object = GetBackReferencedObject(data & kSpaceMask);
} else if (where == kRootArray) {
int id = source_.GetInt();
Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(id);
new_object = isolate->heap()->root(root_index);
emit_write_barrier = isolate->heap()->InNewSpace(new_object);
hot_objects_.Add(HeapObject::cast(new_object));
} else if (where == kPartialSnapshotCache) {
int cache_index = source_.GetInt();
new_object = isolate->partial_snapshot_cache()->at(cache_index);
emit_write_barrier = isolate->heap()->InNewSpace(new_object);
} else if (where == kExternalReference) {
int skip = source_.GetInt();
current =
reinterpret_cast<Object**>(reinterpret_cast<Address>(current) + skip);
uint32_t reference_id = static_cast<uint32_t>(source_.GetInt());
Address address = external_reference_table_->address(reference_id);
new_object = reinterpret_cast<Object*>(address);
} else if (where == kAttachedReference) {
int index = source_.GetInt();
new_object = *attached_objects_[index];
emit_write_barrier = isolate->heap()->InNewSpace(new_object);
} else {
DCHECK(where == kBuiltin);
DCHECK(deserializing_user_code());
int builtin_id = source_.GetInt();
DCHECK_LE(0, builtin_id);
DCHECK_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;
}
if (within == kInnerPointer) {
DCHECK(how == kFromCode);
if (new_object->IsCode()) {
Code* new_code_object = Code::cast(new_object);
new_object =
reinterpret_cast<Object*>(new_code_object->instruction_start());
} else {
Cell* cell = Cell::cast(new_object);
new_object = reinterpret_cast<Object*>(cell->ValueAddress());
}
}
if (how == kFromCode) {
Address location_of_branch_data = reinterpret_cast<Address>(current);
Assembler::deserialization_set_special_target_at(
isolate, location_of_branch_data,
Code::cast(HeapObject::FromAddress(current_object_address)),
reinterpret_cast<Address>(new_object));
location_of_branch_data += Assembler::kSpecialTargetSize;
current = reinterpret_cast<Object**>(location_of_branch_data);
current_was_incremented = true;
} else {
UnalignedCopy(current, &new_object);
}
}
if (emit_write_barrier && write_barrier_needed) {
Address current_address = reinterpret_cast<Address>(current);
SLOW_DCHECK(isolate->heap()->ContainsSlow(current_object_address));
isolate->heap()->RecordWrite(
HeapObject::FromAddress(current_object_address),
reinterpret_cast<Object**>(current_address),
*reinterpret_cast<Object**>(current_address));
}
if (!current_was_incremented) {
current++;
}
return current;
}
} // namespace internal
} // namespace v8
......@@ -110,6 +110,14 @@ class Deserializer : public SerializerDeserializer {
// the heap. Return false if the object content has been deferred.
bool ReadData(Object** start, Object** end, int space,
Address object_address);
// A helper function for ReadData, templatized on the bytecode for efficiency.
// Returns the new value of {current}.
template <int where, int how, int within, int space_number_if_any>
inline Object** ReadDataCase(Isolate* isolate, Object** current,
Address current_object_address, byte data,
bool write_barrier_needed);
void ReadObject(int space_number, Object** write_back);
Address Allocate(int space_index, int size);
......@@ -120,7 +128,7 @@ class Deserializer : public SerializerDeserializer {
Isolate* isolate_;
// Objects from the attached object descriptions in the serialized user code.
List<Handle<HeapObject> > attached_objects_;
List<Handle<HeapObject>> attached_objects_;
SnapshotByteSource source_;
uint32_t magic_number_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment