Revert "[vm/aot] Fill in names of properties in snapshot profile."
This reverts commit 465f8595ec1bd455edc7e91fd220db4be06cca6e as it
breaks windows and mac bots.
Change-Id: I94a939d711f69a28f405ee32680315ad6677b09e
Reviewed-on: https://dart-review.googlesource.com/c/85722
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
diff --git a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
index 000ddcc..ede572c 100644
--- a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
+++ b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
@@ -12,13 +12,20 @@
return "/" + segments.join("/");
}
-test(String sdkRoot, {bool useElf: false}) async {
+test(bool use_elf) async {
if (Platform.isWindows) return;
- if (Platform.isMacOS && useElf) return;
+ if (Platform.isMacOS && use_elf) return;
+
+ final String outputDir = Platform.isMacOS ? "xcodebuild" : "out";
+
+ final List<String> sdkBaseSegments =
+ Uri.file(Platform.resolvedExecutable).pathSegments.toList();
+ sdkBaseSegments.replaceRange(
+ sdkBaseSegments.indexOf(outputDir), sdkBaseSegments.length, []);
// Generate the snapshot profile.
- final String thisTestPath =
- "$sdkRoot/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart";
+ final String thisTestPath = path(sdkBaseSegments) +
+ "/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart";
final Directory temp = await Directory.systemTemp.createTemp();
final String snapshotPath = temp.path + "/test.snap";
@@ -29,20 +36,20 @@
snapshotPath,
];
- if (useElf) {
+ if (use_elf) {
precompiler2Args.insert(0, "--build-elf");
}
final ProcessResult result = await Process.run(
"pkg/vm/tool/precompiler2",
precompiler2Args,
- workingDirectory: sdkRoot,
+ workingDirectory: path(sdkBaseSegments),
runInShell: true,
);
// The precompiler2 script tried using GCC for the wrong architecture. We
// don't have a workaround for this now.
- if (useElf &&
+ if (use_elf &&
result.exitCode != 0 &&
result.stderr.contains("Assembler messages")) {
return;
@@ -84,7 +91,7 @@
// Verify that the actual size of the snapshot is close to the sum of the
// shallow sizes of all objects in the profile. They will not be exactly equal
// because of global headers and padding.
- if (useElf) {
+ if (use_elf) {
await Process.run("strip", [snapshotPath]);
}
final int actual = await File(snapshotPath).length();
@@ -92,85 +99,7 @@
Expect.isTrue((actual - expected).abs() / actual < 0.01);
}
-Match matchComplete(RegExp regexp, String line) {
- Match match = regexp.firstMatch(line);
- if (match == null) return match;
- if (match.start != 0 || match.end != line.length) return null;
- return match;
-}
-
-// All fields of "Raw..." classes defined in "raw_object.h" must be included in
-// the giant macro in "raw_object_fields.cc". This function attempts to check
-// that with some basic regexes.
-testMacros(String sdkRoot) async {
- const String className = "([a-z0-9A-Z]+)";
- const String rawClass = "Raw$className";
- const String fieldName = "([a-z0-9A-Z_]+)";
-
- final Map<String, Set<String>> fields = {};
-
- final String rawObjectFieldsPath = "$sdkRoot/runtime/vm/raw_object_fields.cc";
- final RegExp fieldEntry = RegExp(" *F\\($className, $fieldName\\) *\\\\?");
-
- await for (String line in File(rawObjectFieldsPath)
- .openRead()
- .transform(utf8.decoder)
- .transform(LineSplitter())) {
- Match match = matchComplete(fieldEntry, line);
- if (match != null) {
- fields
- .putIfAbsent(match.group(1), () => Set<String>())
- .add(match.group(2));
- }
- }
-
- final RegExp classStart = RegExp("class $rawClass : public $rawClass {");
- final RegExp classEnd = RegExp("}");
- final RegExp field = RegExp(" $rawClass. +$fieldName;.*");
-
- final String rawObjectPath = "$sdkRoot/runtime/vm/raw_object.h";
-
- String currentClass;
- bool hasMissingFields = false;
- await for (String line in File(rawObjectPath)
- .openRead()
- .transform(utf8.decoder)
- .transform(LineSplitter())) {
- Match match = matchComplete(classStart, line);
- if (match != null) {
- currentClass = match.group(1);
- continue;
- }
-
- match = matchComplete(classEnd, line);
- if (match != null) {
- currentClass = null;
- continue;
- }
-
- match = matchComplete(field, line);
- if (match != null && currentClass != null) {
- if (!fields[currentClass].contains(match.group(2))) {
- hasMissingFields = true;
- print("$currentClass is missing ${match.group(2)}.");
- }
- }
- }
-
- if (hasMissingFields) {
- Expect.fail(
- "runtime/vm/raw_object_fields.cc misses some fields. Please update it to match raw_object.h.");
- }
-}
-
main() async {
- final List<String> sdkBaseSegments =
- Uri.file(Platform.resolvedExecutable).pathSegments.toList();
- sdkBaseSegments
- .replaceRange(sdkBaseSegments.length - 3, sdkBaseSegments.length, []);
- String sdkRoot = path(sdkBaseSegments);
-
- test(sdkRoot, useElf: false);
- test(sdkRoot, useElf: true);
- testMacros(sdkRoot);
+ test(false);
+ test(true);
}
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 118143ed..acbd08a 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -299,9 +299,9 @@
s->Write<bool>(type_args->IsCanonical());
intptr_t hash = Smi::Value(type_args->ptr()->hash_);
s->Write<int32_t>(hash);
- WriteField(type_args, instantiations_);
+ s->WriteRef(type_args->ptr()->instantiations_);
for (intptr_t j = 0; j < length; j++) {
- s->WriteElementRef(type_args->ptr()->types()[j], j);
+ s->WriteRef(type_args->ptr()->types()[j]);
}
}
}
@@ -641,11 +641,11 @@
RawClosureData* data = objects_[i];
AutoTraceObject(data);
if (s->kind() != Snapshot::kFullAOT) {
- WriteField(data, context_scope_);
+ s->WriteRef(data->ptr()->context_scope_);
}
- WriteField(data, parent_function_);
- WriteField(data, signature_type_);
- WriteField(data, closure_);
+ s->WriteRef(data->ptr()->parent_function_);
+ s->WriteRef(data->ptr()->signature_type_);
+ s->WriteRef(data->ptr()->closure_);
}
}
@@ -882,39 +882,39 @@
intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawField* field = objects_[i];
- AutoTraceObjectName(field, field->ptr()->name_);
+ AutoTraceObject(field);
- WriteField(field, name_);
- WriteField(field, owner_);
- WriteField(field, type_);
+ s->WriteRef(field->ptr()->name_);
+ s->WriteRef(field->ptr()->owner_);
+ s->WriteRef(field->ptr()->type_);
// Write out the initial static value or field offset.
if (Field::StaticBit::decode(field->ptr()->kind_bits_)) {
if (kind == Snapshot::kFullAOT) {
// For precompiled static fields, the value was already reset and
// initializer_ now contains a Function.
- WriteField(field, value_.static_value_);
+ s->WriteRef(field->ptr()->value_.static_value_);
} else if (Field::ConstBit::decode(field->ptr()->kind_bits_)) {
// Do not reset const fields.
- WriteField(field, value_.static_value_);
+ s->WriteRef(field->ptr()->value_.static_value_);
} else {
// Otherwise, for static fields we write out the initial static value.
- WriteField(field, initializer_.saved_value_);
+ s->WriteRef(field->ptr()->initializer_.saved_value_);
}
} else {
- WriteField(field, value_.offset_);
+ s->WriteRef(field->ptr()->value_.offset_);
}
// Write out the initializer function or saved initial value.
if (kind == Snapshot::kFullAOT) {
- WriteField(field, initializer_.precompiled_);
+ s->WriteRef(field->ptr()->initializer_.precompiled_);
} else {
- WriteField(field, initializer_.saved_value_);
+ s->WriteRef(field->ptr()->initializer_.saved_value_);
}
if (kind != Snapshot::kFullAOT) {
// Write out the guarded list length.
- WriteField(field, guarded_list_length_);
+ s->WriteRef(field->ptr()->guarded_list_length_);
}
if (kind == Snapshot::kFullJIT) {
- WriteField(field, dependent_code_);
+ s->WriteRef(field->ptr()->dependent_code_);
}
if (kind != Snapshot::kFullAOT) {
@@ -1369,29 +1369,29 @@
s->WriteInstructions(code->ptr()->active_instructions_, code);
}
- WriteField(code, object_pool_);
- WriteField(code, owner_);
- WriteField(code, exception_handlers_);
- WriteField(code, pc_descriptors_);
+ s->WriteRef(code->ptr()->object_pool_);
+ s->WriteRef(code->ptr()->owner_);
+ s->WriteRef(code->ptr()->exception_handlers_);
+ s->WriteRef(code->ptr()->pc_descriptors_);
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
- WriteField(code, catch_entry_.catch_entry_moves_maps_);
+ s->WriteRef(code->ptr()->catch_entry_.catch_entry_moves_maps_);
#else
- WriteField(code, catch_entry_.variables_);
+ s->WriteRef(code->ptr()->catch_entry_.variables_);
#endif
- WriteField(code, stackmaps_);
+ s->WriteRef(code->ptr()->stackmaps_);
if (FLAG_dwarf_stack_traces) {
- WriteFieldValue(inlined_id_to_function_, Array::null());
- WriteFieldValue(code_source_map_, CodeSourceMap::null());
+ s->WriteRef(Array::null());
+ s->WriteRef(CodeSourceMap::null());
} else {
- WriteField(code, inlined_id_to_function_);
- WriteField(code, code_source_map_);
+ s->WriteRef(code->ptr()->inlined_id_to_function_);
+ s->WriteRef(code->ptr()->code_source_map_);
}
if (kind == Snapshot::kFullJIT) {
- WriteField(code, deopt_info_array_);
- WriteField(code, static_calls_target_table_);
+ s->WriteRef(code->ptr()->deopt_info_array_);
+ s->WriteRef(code->ptr()->static_calls_target_table_);
}
- NOT_IN_PRODUCT(WriteField(code, await_token_positions_));
- NOT_IN_PRODUCT(WriteField(code, return_address_metadata_));
+ NOT_IN_PRODUCT(s->WriteRef(code->ptr()->await_token_positions_));
+ NOT_IN_PRODUCT(s->WriteRef(code->ptr()->return_address_metadata_));
s->Write<int32_t>(code->ptr()->state_bits_);
}
@@ -1607,11 +1607,11 @@
// Natives can run while precompiling, becoming linked and
// switching their stub. Reset to the initial stub used for
// lazy-linking.
- s->WriteElementRef(StubCode::CallBootstrapNative().raw(), j);
+ s->WriteRef(StubCode::CallBootstrapNative().raw());
break;
}
#endif
- s->WriteElementRef(entry.raw_obj_, j);
+ s->WriteRef(entry.raw_obj_);
break;
}
case ObjectPool::kImmediate: {
@@ -1631,7 +1631,7 @@
payload->trampoline = NULL;
payload->native_function = NULL;
}
- s->WriteElementRef(raw, j);
+ s->WriteRef(raw);
break;
}
case ObjectPool::kNativeFunction:
@@ -1758,18 +1758,13 @@
for (intptr_t i = 0; i < count; i++) {
RawObject* object = objects_[i];
s->AssignRef(object);
- if (cid_ == kOneByteStringCid || cid_ == kTwoByteStringCid) {
- s->TraceStartWritingObject(name(), object, String::RawCast(object));
- } else {
- s->TraceStartWritingObject(name(), object, nullptr);
- }
+ AutoTraceObject(object);
uint32_t offset = s->GetDataOffset(object);
s->TraceDataOffset(offset);
ASSERT(Utils::IsAligned(offset, kObjectAlignment));
ASSERT(offset > running_offset);
s->WriteUnsigned((offset - running_offset) >> kObjectAlignmentLog2);
running_offset = offset;
- s->TraceEndWritingObject();
}
}
@@ -1843,7 +1838,7 @@
AutoTraceObject(handlers);
intptr_t length = handlers->ptr()->num_entries_;
s->WriteUnsigned(length);
- WriteField(handlers, handled_types_data_);
+ s->WriteRef(handlers->ptr()->handled_types_data_);
for (intptr_t j = 0; j < length; j++) {
const ExceptionHandlerInfo& info = handlers->ptr()->data()[j];
s->Write<uint32_t>(info.handler_pc_offset);
@@ -1939,9 +1934,9 @@
AutoTraceObject(context);
intptr_t length = context->ptr()->num_variables_;
s->WriteUnsigned(length);
- WriteField(context, parent_);
+ s->WriteRef(context->ptr()->parent_);
for (intptr_t j = 0; j < length; j++) {
- s->WriteElementRef(context->ptr()->data()[j], j);
+ s->WriteRef(context->ptr()->data()[j]);
}
}
}
@@ -2301,7 +2296,7 @@
for (intptr_t i = 0; i < count; i++) {
RawSubtypeTestCache* cache = objects_[i];
AutoTraceObject(cache);
- WriteField(cache, cache_);
+ s->WriteRef(cache->ptr()->cache_);
}
}
@@ -2530,7 +2525,7 @@
while (offset < next_field_offset) {
RawObject* raw_obj = *reinterpret_cast<RawObject**>(
reinterpret_cast<uword>(instance->ptr()) + offset);
- s->WriteElementRef(raw_obj, offset);
+ s->WriteRef(raw_obj);
offset += kWordSize;
}
}
@@ -3815,7 +3810,7 @@
AutoTraceObject(map);
s->Write<bool>(map->IsCanonical());
- WriteField(map, type_arguments_);
+ s->WriteRef(map->ptr()->type_arguments_);
const intptr_t used_data = Smi::Value(map->ptr()->used_data_);
ASSERT((used_data & 1) == 0); // Keys + values, so must be even.
@@ -3830,8 +3825,8 @@
RawObject* key = data_elements[i];
if (key != data_array) {
RawObject* value = data_elements[i + 1];
- s->WriteElementRef(key, i);
- s->WriteElementRef(value, i + 1);
+ s->WriteRef(key);
+ s->WriteRef(value);
}
}
}
@@ -3939,9 +3934,9 @@
intptr_t length = Smi::Value(array->ptr()->length_);
s->WriteUnsigned(length);
s->Write<bool>(array->IsCanonical());
- WriteField(array, type_arguments_);
+ s->WriteRef(array->ptr()->type_arguments_);
for (intptr_t j = 0; j < length; j++) {
- s->WriteElementRef(array->ptr()->data()[j], j);
+ s->WriteRef(array->ptr()->data()[j]);
}
}
}
@@ -4196,9 +4191,6 @@
for (intptr_t i = 0; i < num_cids_; i++) {
clusters_by_cid_[i] = NULL;
}
- if (profile_writer_ != nullptr) {
- offsets_table_ = new (zone_) OffsetsTable(zone_);
- }
}
Serializer::~Serializer() {
@@ -4210,14 +4202,11 @@
RawString* name) {
if (profile_writer_ == nullptr) return;
- intptr_t cid = -1;
intptr_t id = 0;
if (obj->IsHeapObject()) {
id = heap_->GetObjectId(obj);
- cid = obj->GetClassId();
} else {
id = smi_ids_.Lookup(Smi::RawCast(obj))->id_;
- cid = Smi::kClassId;
}
ASSERT(id != 0);
@@ -4228,21 +4217,20 @@
name_str = str.ToCString();
}
- object_currently_writing_.object_ = obj;
- object_currently_writing_.id_ = id;
- object_currently_writing_.stream_start_ = stream_.Position();
- object_currently_writing_.cid_ = cid;
+ object_currently_writing_id_ = id;
profile_writer_->SetObjectTypeAndName(
{V8SnapshotProfileWriter::kSnapshot, id}, type, name_str);
+ object_currently_writing_start_ = stream_.Position();
}
void Serializer::TraceEndWritingObject() {
if (profile_writer_ != nullptr) {
- ASSERT(object_currently_writing_.id_ != 0);
+ ASSERT(object_currently_writing_id_ != 0);
profile_writer_->AttributeBytesTo(
- {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
- stream_.Position() - object_currently_writing_.stream_start_);
- object_currently_writing_ = ProfilingObject();
+ {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_id_},
+ stream_.Position() - object_currently_writing_start_);
+ object_currently_writing_id_ = 0;
+ object_currently_writing_start_ = 0;
}
}
@@ -4389,33 +4377,24 @@
// course, the space taken for the reference is profiled.
if (profile_writer_ != nullptr && offset >= 0) {
// Instructions cannot be roots.
- ASSERT(object_currently_writing_.id_ != 0);
+ ASSERT(object_currently_writing_id_ != 0);
auto offset_space = vm_ ? V8SnapshotProfileWriter::kVmText
: V8SnapshotProfileWriter::kIsolateText;
- V8SnapshotProfileWriter::ObjectId to_object = {
- offset_space, offset < 0 ? -offset : offset};
- V8SnapshotProfileWriter::ObjectId from_object = {
- V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_};
profile_writer_->AttributeReferenceTo(
- from_object, {to_object, V8SnapshotProfileWriter::Reference::kProperty,
- profile_writer_->EnsureString("<instructions>")});
+ {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_id_},
+ {offset_space, offset < 0 ? -offset : offset});
}
}
void Serializer::TraceDataOffset(uint32_t offset) {
if (profile_writer_ != nullptr) {
// ROData cannot be roots.
- ASSERT(object_currently_writing_.id_ != 0);
+ ASSERT(object_currently_writing_id_ != 0);
auto offset_space = vm_ ? V8SnapshotProfileWriter::kVmData
: V8SnapshotProfileWriter::kIsolateData;
- V8SnapshotProfileWriter::ObjectId from_object = {
- V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_};
- V8SnapshotProfileWriter::ObjectId to_object = {offset_space, offset};
- // TODO(sjindel): Give this edge a more appropriate type than element
- // (internal, maybe?).
profile_writer_->AttributeReferenceTo(
- from_object,
- {to_object, V8SnapshotProfileWriter::Reference::kElement, 0});
+ {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_id_},
+ {offset_space, offset});
}
}
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index 412ffb5..79bdd8d 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -14,7 +14,6 @@
#include "vm/hash_map.h"
#include "vm/heap/heap.h"
#include "vm/object.h"
-#include "vm/raw_object_fields.h"
#include "vm/snapshot.h"
#include "vm/type_testing_stubs.h"
#include "vm/v8_snapshot_writer.h"
@@ -237,8 +236,7 @@
}
void Align(intptr_t alignment) { stream_.Align(alignment); }
- private:
- intptr_t WriteRefId(RawObject* object) {
+ void WriteRef(RawObject* object, bool is_root = false) {
intptr_t id = 0;
if (!object->IsHeapObject()) {
RawSmi* smi = Smi::RawCast(object);
@@ -253,75 +251,35 @@
id = heap_->GetObjectId(object);
if (id == 0) {
if (object->IsCode() && !Snapshot::IncludesCode(kind_)) {
- return WriteRefId(Object::null());
+ WriteRef(Object::null());
+ return;
}
#if !defined(DART_PRECOMPILED_RUNTIME)
if (object->IsBytecode() && !Snapshot::IncludesBytecode(kind_)) {
- return WriteRefId(Object::null());
+ WriteRef(Object::null());
+ return;
}
#endif // !DART_PRECOMPILED_RUNTIME
if (object->IsSendPort()) {
// TODO(rmacnak): Do a better job of resetting fields in
// precompilation and assert this is unreachable.
- return WriteRefId(Object::null());
+ WriteRef(Object::null());
+ return;
}
FATAL("Missing ref");
}
}
- return id;
- }
- public:
- void WriteRootRef(RawObject* object) {
- intptr_t id = WriteRefId(object);
WriteUnsigned(id);
- if (profile_writer_ != nullptr) {
- profile_writer_->AddRoot({V8SnapshotProfileWriter::kSnapshot, id});
- }
- }
- void WriteElementRef(RawObject* object, intptr_t index) {
- intptr_t id = WriteRefId(object);
- WriteUnsigned(id);
if (profile_writer_ != nullptr) {
- profile_writer_->AttributeReferenceTo(
- {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
- {{V8SnapshotProfileWriter::kSnapshot, id},
- V8SnapshotProfileWriter::Reference::kElement,
- index});
- }
- }
-
- void WritePropertyRef(RawObject* object, const char* property) {
- intptr_t id = WriteRefId(object);
- WriteUnsigned(id);
- if (profile_writer_ != nullptr) {
- profile_writer_->AttributeReferenceTo(
- {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
- {{V8SnapshotProfileWriter::kSnapshot, id},
- V8SnapshotProfileWriter::Reference::kProperty,
- profile_writer_->EnsureString(property)});
- }
- }
-
- void WriteOffsetRef(RawObject* object, intptr_t offset) {
- intptr_t id = WriteRefId(object);
- WriteUnsigned(id);
- if (profile_writer_ != nullptr) {
- const char* property = offsets_table_->FieldNameForOffset(
- object_currently_writing_.cid_, offset);
- if (property != nullptr) {
+ if (object_currently_writing_id_ != 0) {
profile_writer_->AttributeReferenceTo(
- {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
- {{V8SnapshotProfileWriter::kSnapshot, id},
- V8SnapshotProfileWriter::Reference::kProperty,
- profile_writer_->EnsureString(property)});
+ {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_id_},
+ {V8SnapshotProfileWriter::kSnapshot, id});
} else {
- profile_writer_->AttributeReferenceTo(
- {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
- {{V8SnapshotProfileWriter::kSnapshot, id},
- V8SnapshotProfileWriter::Reference::kElement,
- offset});
+ ASSERT(is_root);
+ profile_writer_->AddRoot({V8SnapshotProfileWriter::kSnapshot, id});
}
}
}
@@ -331,8 +289,7 @@
RawObject** from = obj->from();
RawObject** to = obj->to_snapshot(kind(), args...);
for (RawObject** p = from; p <= to; p++) {
- WriteOffsetRef(*p, (p - reinterpret_cast<RawObject**>(obj->ptr())) *
- sizeof(RawObject*));
+ WriteRef(*p);
}
}
@@ -345,6 +302,10 @@
}
}
+ void WriteRootRef(RawObject* object) {
+ WriteRef(object, /* is_root = */ true);
+ }
+
void WriteTokenPosition(TokenPosition pos) {
Write<int32_t>(pos.SnapshotEncode());
}
@@ -385,13 +346,8 @@
bool vm_;
V8SnapshotProfileWriter* profile_writer_ = nullptr;
- struct ProfilingObject {
- RawObject* object_ = nullptr;
- intptr_t id_ = 0;
- intptr_t stream_start_ = 0;
- intptr_t cid_ = -1;
- } object_currently_writing_;
- OffsetsTable* offsets_table_ = nullptr;
+ intptr_t object_currently_writing_id_ = 0;
+ intptr_t object_currently_writing_start_ = 0;
#if defined(SNAPSHOT_BACKTRACE)
RawObject* current_parent_;
@@ -407,14 +363,14 @@
#define AutoTraceObjectName(obj, str) \
SerializerWritingObjectScope scope_##__COUNTER__(s, name(), obj, str)
-#define WriteFieldValue(field, value) s->WritePropertyRef(value, #field);
+#define WriteField(obj, field) s->WriteRef(obj->ptr()->field);
+
+#define WriteFieldValue(field, value) s->WriteRef(value);
#define WriteFromTo(obj, ...) s->WriteFromTo(obj, ##__VA_ARGS__);
#define PushFromTo(obj, ...) s->PushFromTo(obj, ##__VA_ARGS__);
-#define WriteField(obj, field) s->WritePropertyRef(obj->ptr()->field, #field)
-
struct SerializerWritingObjectScope {
SerializerWritingObjectScope(Serializer* serializer,
const char* type,
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index cd8ef90..f61c467 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -294,7 +294,7 @@
for (intptr_t i = 0; i < objects_.length(); i++) {
const Object& obj = *objects_[i].obj_;
- AutoTraceImage(obj, section_start, stream);
+ AutoTraceImage(section_start, stream, "ROData");
NoSafepointScope no_safepoint;
uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag;
@@ -615,7 +615,7 @@
NoSafepointScope no_safepoint;
for (intptr_t i = 0; i < instructions_.length(); i++) {
const Instructions& insns = *instructions_[i].insns_;
- AutoTraceImage(insns, 0, &this->instructions_blob_stream_);
+ AutoTraceImage(0, &this->instructions_blob_stream_, "Instructions");
uword beginning = reinterpret_cast<uword>(insns.raw_ptr());
uword entry = beginning + Instructions::HeaderSize();
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index a56c87e..33c0956 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -13,8 +13,6 @@
#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/hash_map.h"
-#include "vm/object.h"
-#include "vm/reusable_handles.h"
#include "vm/v8_snapshot_writer.h"
namespace dart {
@@ -186,10 +184,10 @@
DISALLOW_COPY_AND_ASSIGN(ImageWriter);
};
-#define AutoTraceImage(object, section_offset, stream) \
+#define AutoTraceImage(section_offset, stream, type_name) \
auto AutoTraceImagObjectScopeVar##__COUNTER__ = \
TraceImageObjectScope<std::remove_pointer<decltype(stream)>::type>( \
- this, section_offset, stream, object);
+ this, section_offset, stream, type_name);
template <typename T>
class TraceImageObjectScope {
@@ -197,22 +195,15 @@
TraceImageObjectScope(ImageWriter* writer,
intptr_t section_offset,
const T* stream,
- const Object& object)
+ const char* type)
: writer_(writer),
stream_(stream),
section_offset_(section_offset),
start_offset_(stream_->Position() - section_offset) {
if (writer_->profile_writer_ != nullptr) {
- Thread* thread = Thread::Current();
- REUSABLE_CLASS_HANDLESCOPE(thread);
- REUSABLE_STRING_HANDLESCOPE(thread);
- Class& klass = thread->ClassHandle();
- String& name = thread->StringHandle();
- klass = object.clazz();
- name = klass.UserVisibleName();
ASSERT(writer_->offset_space_ != V8SnapshotProfileWriter::kSnapshot);
writer_->profile_writer_->SetObjectTypeAndName(
- {writer_->offset_space_, start_offset_}, name.ToCString(), nullptr);
+ {writer_->offset_space_, start_offset_}, type, nullptr);
}
}
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 01f4cae..3f9ef48 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -267,7 +267,6 @@
friend class InterpreterHelpers; \
friend class Simulator; \
friend class SimulatorHelpers; \
- friend class OffsetsTable; \
DISALLOW_ALLOCATION(); \
DISALLOW_IMPLICIT_CONSTRUCTORS(Raw##object)
@@ -879,7 +878,6 @@
friend class Precompiler; // GetClassId
friend class ObjectOffsetTrait; // GetClassId
friend class WriteBarrierUpdateVisitor; // CheckHeapPointerStore
- friend class OffsetsTable;
DISALLOW_ALLOCATION();
DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject);
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
deleted file mode 100644
index 9e1f8e5..0000000
--- a/runtime/vm/raw_object_fields.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/raw_object_fields.h"
-
-namespace dart {
-
-#if defined(DART_PRECOMPILER)
-
-#define RAW_CLASSES_AND_FIELDS(F) \
- F(Class, name_) \
- F(Class, user_name_) \
- F(Class, functions_) \
- F(Class, functions_hash_table_) \
- F(Class, fields_) \
- F(Class, offset_in_words_to_field_) \
- F(Class, interfaces_) \
- F(Class, script_) \
- F(Class, library_) \
- F(Class, type_parameters_) \
- F(Class, super_type_) \
- F(Class, mixin_) \
- F(Class, signature_function_) \
- F(Class, constants_) \
- F(Class, canonical_type_) \
- F(Class, invocation_dispatcher_cache_) \
- F(Class, allocation_stub_) \
- F(Class, direct_implementors_) \
- F(Class, direct_subclasses_) \
- F(Class, dependent_code_) \
- F(PatchClass, patched_class_) \
- F(PatchClass, origin_class_) \
- F(PatchClass, script_) \
- F(PatchClass, library_kernel_data_) \
- F(Function, name_) \
- F(Function, owner_) \
- F(Function, result_type_) \
- F(Function, parameter_types_) \
- F(Function, parameter_names_) \
- F(Function, type_parameters_) \
- F(Function, data_) \
- F(Function, ic_data_array_) \
- F(Function, code_) \
- F(ClosureData, context_scope_) \
- F(ClosureData, parent_function_) \
- F(ClosureData, signature_type_) \
- F(ClosureData, closure_) \
- F(SignatureData, parent_function_) \
- F(SignatureData, signature_type_) \
- F(RedirectionData, type_) \
- F(RedirectionData, identifier_) \
- F(RedirectionData, target_) \
- F(Field, name_) \
- F(Field, owner_) \
- F(Field, type_) \
- F(Field, guarded_list_length_) \
- F(Field, dependent_code_) \
- F(Field, type_test_cache_) \
- F(Script, url_) \
- F(Script, resolved_url_) \
- F(Script, compile_time_constants_) \
- F(Script, line_starts_) \
- F(Script, debug_positions_) \
- F(Script, yield_positions_) \
- F(Script, kernel_program_info_) \
- F(Script, source_) \
- F(Library, name_) \
- F(Library, url_) \
- F(Library, private_key_) \
- F(Library, dictionary_) \
- F(Library, metadata_) \
- F(Library, toplevel_class_) \
- F(Library, patch_classes_) \
- F(Library, imports_) \
- F(Library, exports_) \
- F(Library, load_error_) \
- F(Library, kernel_data_) \
- F(Library, resolved_names_) \
- F(Library, exported_names_) \
- F(Library, loaded_scripts_) \
- F(Namespace, library_) \
- F(Namespace, show_names_) \
- F(Namespace, hide_names_) \
- F(Namespace, metadata_field_) \
- F(KernelProgramInfo, string_offsets_) \
- F(KernelProgramInfo, string_data_) \
- F(KernelProgramInfo, canonical_names_) \
- F(KernelProgramInfo, metadata_payloads_) \
- F(KernelProgramInfo, metadata_mappings_) \
- F(KernelProgramInfo, scripts_) \
- F(KernelProgramInfo, constants_) \
- F(KernelProgramInfo, potential_natives_) \
- F(KernelProgramInfo, potential_pragma_functions_) \
- F(KernelProgramInfo, constants_table_) \
- F(KernelProgramInfo, libraries_cache_) \
- F(KernelProgramInfo, classes_cache_) \
- F(Code, object_pool_) \
- F(Code, instructions_) \
- F(Code, owner_) \
- F(Code, exception_handlers_) \
- F(Code, pc_descriptors_) \
- F(Code, stackmaps_) \
- F(Code, inlined_id_to_function_) \
- F(Code, code_source_map_) \
- F(Bytecode, object_pool_) \
- F(Bytecode, instructions_) \
- F(Bytecode, function_) \
- F(Bytecode, exception_handlers_) \
- F(Bytecode, pc_descriptors_) \
- F(ExceptionHandlers, handled_types_data_) \
- F(Context, parent_) \
- F(SingleTargetCache, target_) \
- F(UnlinkedCall, target_name_) \
- F(UnlinkedCall, args_descriptor_) \
- F(ICData, ic_data_) \
- F(ICData, target_name_) \
- F(ICData, args_descriptor_) \
- F(ICData, owner_) \
- F(MegamorphicCache, buckets_) \
- F(MegamorphicCache, mask_) \
- F(MegamorphicCache, target_name_) \
- F(MegamorphicCache, args_descriptor_) \
- F(SubtypeTestCache, cache_) \
- F(ApiError, message_) \
- F(LanguageError, previous_error_) \
- F(LanguageError, script_) \
- F(LanguageError, message_) \
- F(LanguageError, formatted_message_) \
- F(UnhandledException, exception_) \
- F(UnhandledException, stacktrace_) \
- F(UnwindError, message_) \
- F(LibraryPrefix, name_) \
- F(LibraryPrefix, importer_) \
- F(LibraryPrefix, imports_) \
- F(LibraryPrefix, dependent_code_) \
- F(TypeArguments, instantiations_) \
- F(TypeArguments, length_) \
- F(TypeArguments, hash_) \
- F(Type, type_class_id_) \
- F(Type, arguments_) \
- F(Type, hash_) \
- F(TypeRef, type_) \
- F(TypeParameter, name_) \
- F(TypeParameter, hash_) \
- F(TypeParameter, bound_) \
- F(TypeParameter, parameterized_function_) \
- F(BoundedType, type_) \
- F(BoundedType, bound_) \
- F(BoundedType, hash_) \
- F(BoundedType, type_parameter_) \
- F(MixinAppType, super_type_) \
- F(MixinAppType, mixin_types_) \
- F(Closure, instantiator_type_arguments_) \
- F(Closure, function_type_arguments_) \
- F(Closure, delayed_type_arguments_) \
- F(Closure, function_) \
- F(Closure, context_) \
- F(Closure, hash_) \
- F(String, length_) \
- F(String, hash_) \
- F(Array, type_arguments_) \
- F(Array, length_) \
- F(GrowableObjectArray, type_arguments_) \
- F(GrowableObjectArray, length_) \
- F(GrowableObjectArray, data_) \
- F(LinkedHashMap, type_arguments_) \
- F(LinkedHashMap, index_) \
- F(LinkedHashMap, hash_mask_) \
- F(LinkedHashMap, data_) \
- F(LinkedHashMap, used_data_) \
- F(LinkedHashMap, deleted_keys_) \
- F(TypedData, length_) \
- F(ExternalTypedData, length_) \
- F(ReceivePort, send_port_) \
- F(ReceivePort, handler_) \
- F(StackTrace, async_link_) \
- F(StackTrace, code_array_) \
- F(StackTrace, pc_offset_array_) \
- F(RegExp, num_bracket_expressions_) \
- F(RegExp, pattern_) \
- F(RegExp, external_one_byte_function_) \
- F(RegExp, external_two_byte_function_) \
- F(RegExp, external_one_byte_sticky_function_) \
- F(RegExp, external_two_byte_sticky_function_) \
- F(WeakProperty, key_) \
- F(WeakProperty, value_) \
- F(MirrorReference, referent_) \
- F(UserTag, label_)
-
-OffsetsTable::OffsetsTable(Zone* zone) : cached_offsets_(zone) {
- for (intptr_t i = 0; offsets_table[i].class_id != -1; ++i) {
- OffsetsTableEntry entry = offsets_table[i];
- cached_offsets_.Insert({{entry.class_id, entry.offset}, entry.field_name});
- }
-}
-
-const char* OffsetsTable::FieldNameForOffset(intptr_t class_id,
- intptr_t offset) {
- return cached_offsets_.LookupValue({class_id, offset});
-}
-
-#define DEFINE_OFFSETS_TABLE_ENTRY(class_name, field_name) \
- {class_name::kClassId, #field_name, OFFSET_OF(Raw##class_name, field_name)},
-
-// clang-format off
-OffsetsTable::OffsetsTableEntry OffsetsTable::offsets_table[] = {
- RAW_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
- {-1, nullptr, -1}
-};
-// clang-format on
-
-#undef DEFINE_OFFSETS_TABLE_ENTRY
-
-#endif
-
-} // namespace dart
diff --git a/runtime/vm/raw_object_fields.h b/runtime/vm/raw_object_fields.h
deleted file mode 100644
index 9f67643..0000000
--- a/runtime/vm/raw_object_fields.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// This file (and "raw_object_fields.cc") provide a kind of reflection that
-// allows us to identify the name of fields in hand-written "Raw..." classes
-// (from "raw_object.h") given the class and the offset within the object. This
-// is used for example by the snapshot profile writer ("v8_snapshot_writer.h")
-// to show the property names of these built-in objects in the snapshot profile.
-
-#ifndef RUNTIME_VM_RAW_OBJECT_FIELDS_H_
-#define RUNTIME_VM_RAW_OBJECT_FIELDS_H_
-
-#include <utility>
-
-#include "vm/hash_map.h"
-#include "vm/object.h"
-#include "vm/raw_object.h"
-
-namespace dart {
-
-#if defined(DART_PRECOMPILER)
-
-class OffsetsTable : public ZoneAllocated {
- public:
- explicit OffsetsTable(Zone* zone);
-
- // Returns 'nullptr' if no offset was found.
- // Otherwise, the returned string is allocated in global static memory.
- const char* FieldNameForOffset(intptr_t cid, intptr_t offset);
-
- private:
- struct OffsetsTableEntry {
- const intptr_t class_id;
- const char* field_name;
- intptr_t offset;
- };
-
- static OffsetsTableEntry offsets_table[];
-
- struct IntAndIntToStringMapTraits {
- typedef std::pair<intptr_t, intptr_t> Key;
- typedef const char* Value;
-
- struct Pair {
- Key key;
- Value value;
- Pair() : key({-1, -1}), value(nullptr) {}
- Pair(Key k, Value v) : key(k), value(v) {}
- };
-
- static Value ValueOf(Pair pair) { return pair.value; }
- static Key KeyOf(Pair pair) { return pair.key; }
- static size_t Hashcode(Key key) { return key.first ^ key.second; }
- static bool IsKeyEqual(Pair x, Key y) {
- return x.key.first == y.first && x.key.second == y.second;
- }
- };
-
- DirectChainedHashMap<IntAndIntToStringMapTraits> cached_offsets_;
-};
-
-#else
-
-class OffsetsTable : public ZoneAllocated {
- public:
- explicit OffsetsTable(Zone* zone) {}
-
- const char* FieldNameForOffset(intptr_t cid, intptr_t offset) {
- return nullptr;
- }
-};
-
-#endif
-
-} // namespace dart
-
-#endif // RUNTIME_VM_RAW_OBJECT_FIELDS_H_
diff --git a/runtime/vm/v8_snapshot_writer.cc b/runtime/vm/v8_snapshot_writer.cc
index ce24a25..e945ca0 100644
--- a/runtime/vm/v8_snapshot_writer.cc
+++ b/runtime/vm/v8_snapshot_writer.cc
@@ -57,7 +57,7 @@
info->type = type_id;
if (name != nullptr) {
- info->name = EnsureString(OS::SCreate(zone_, "[%s] %s", type, name));
+ info->name = EnsureString(name);
} else {
info->name = EnsureString(type);
}
@@ -69,16 +69,18 @@
}
void V8SnapshotProfileWriter::AttributeReferenceTo(ObjectId object_id,
- Reference reference) {
- EnsureId(reference.to_object_id);
+ ObjectId to_object_id) {
+ EnsureId(to_object_id);
NodeInfo* info = EnsureId(object_id);
- ASSERT(reference.offset_or_name >= 0);
- info->edges->Add({
- reference.reference_type == Reference::kElement ? kElement : kProperty,
- reference.offset_or_name,
- reference.to_object_id,
- });
+#if defined(DEBUG)
+ // We should never add a reference twice.
+ for (intptr_t i = 0; i < info->edges->length(); ++i) {
+ ASSERT(info->edges->At(i).to_node != object_id);
+ }
+#endif
+
+ info->edges->Add(EdgeInfo{to_object_id});
++edge_count_;
}
@@ -132,8 +134,9 @@
void V8SnapshotProfileWriter::WriteEdgeInfo(JSONWriter* writer,
const EdgeInfo& info) {
- writer->PrintValue64(info.type);
- writer->PrintValue64(info.name_or_index);
+ writer->PrintValue64(kProperty); // type, not really used atm
+ writer->PrintValue64(
+ kPropertyString); // name_or_index, not really used either
writer->PrintValue64(nodes_.LookupValue(info.to_node).offset);
writer->PrintNewline();
}
@@ -232,8 +235,8 @@
writer->OpenArray("edges");
// Write references from the artificial root to the actual roots.
- for (intptr_t i = 0; i < roots_.length(); ++i) {
- WriteEdgeInfo(writer, {kElement, i, roots_[i]});
+ for (ObjectId root : roots_) {
+ WriteEdgeInfo(writer, {root});
}
ObjectIdToNodeInfoTraits::Pair* entry = nullptr;
diff --git a/runtime/vm/v8_snapshot_writer.h b/runtime/vm/v8_snapshot_writer.h
index fa9ee85..c506b2e 100644
--- a/runtime/vm/v8_snapshot_writer.h
+++ b/runtime/vm/v8_snapshot_writer.h
@@ -11,7 +11,6 @@
#include "vm/allocation.h"
#include "vm/hash_map.h"
#include "vm/json_writer.h"
-#include "vm/object.h"
namespace dart {
@@ -30,7 +29,10 @@
static Key KeyOf(Pair pair) { return pair.key; }
- static size_t Hashcode(Key key) { return String::Hash(key, strlen(key)); }
+ static size_t Hashcode(Key key) {
+ /// SAMIR_TODO
+ return 0;
+ }
static bool IsKeyEqual(Pair x, Key y) { return strcmp(x.key, y) == 0; }
};
@@ -49,22 +51,6 @@
typedef std::pair<IdSpace, intptr_t> ObjectId;
- struct Reference {
- ObjectId to_object_id;
- enum {
- kElement,
- kProperty,
- } reference_type;
- intptr_t offset_or_name;
- };
-
- enum ConstantStrings {
- kUnknownString = 0,
- kPropertyString = 1,
- kObjectString = 2,
- kArtificialRootString = 3,
- };
-
#if !defined(DART_PRECOMPILER)
explicit V8SnapshotProfileWriter(Zone* zone) {}
virtual ~V8SnapshotProfileWriter() {}
@@ -73,9 +59,8 @@
const char* type,
const char* name) {}
void AttributeBytesTo(ObjectId object_id, size_t num_bytes) {}
- void AttributeReferenceTo(ObjectId object_id, Reference reference) {}
+ void AttributeReferenceTo(ObjectId object_id, ObjectId to_object_id) {}
void AddRoot(ObjectId object_id) {}
- intptr_t EnsureString(const char* str) { return 0; }
#else
explicit V8SnapshotProfileWriter(Zone* zone);
virtual ~V8SnapshotProfileWriter() {}
@@ -95,7 +80,7 @@
// Records that a reference to the object with id 'to_object_id' was written
// in order to serialize the object with id 'object_id'. This does not affect
// the number of bytes charged to 'object_id'.
- void AttributeReferenceTo(ObjectId object_id, Reference reference);
+ void AttributeReferenceTo(ObjectId object_id, ObjectId to_object_id);
// Marks an object as being a root in the graph. Used for analysis of the
// graph.
@@ -104,15 +89,12 @@
// Write to a file in the V8 Snapshot Profile (JSON/.heapsnapshot) format.
void Write(const char* file);
- intptr_t EnsureString(const char* str);
-
private:
static constexpr intptr_t kNumNodeFields = 5;
static constexpr intptr_t kNumEdgeFields = 3;
struct EdgeInfo {
- intptr_t type;
- intptr_t name_or_index;
+ // 'type' and 'name_or_index' aren't supported yet.
ObjectId to_node;
};
@@ -149,10 +131,18 @@
static NodeInfo ArtificialRoot();
NodeInfo* EnsureId(ObjectId object_id);
+ intptr_t EnsureString(const char* str);
static intptr_t NodeIdFor(ObjectId id) {
return (id.second << kIdSpaceBits) | id.first;
}
+ enum ConstantStrings {
+ kUnknownString = 0,
+ kPropertyString = 1,
+ kObjectString = 2,
+ kArtificialRootString = 3,
+ };
+
enum ConstantEdgeTypes {
kContext = 0,
kElement = 1,
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index a9b02fc..b0e7872 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -215,8 +215,6 @@
"random.h",
"raw_object.cc",
"raw_object.h",
- "raw_object_fields.cc",
- "raw_object_fields.h",
"raw_object_snapshot.cc",
"regexp.cc",
"regexp.h",