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

Unified Diff: runtime/vm/profiler.cc

Issue 1435533003: Make profiler work without Instructions -> Code pointer (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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 | « runtime/vm/profiler.h ('k') | runtime/vm/profiler_service.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/profiler.cc
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 6edff105306efce455e4fb4e1c16eb294aff0afc..928fe7e0013abd86797c8f6a4fb734b92f4f4432 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -1049,6 +1049,139 @@ void Profiler::SampleThread(Thread* thread,
}
+
+CodeDescriptor::CodeDescriptor(const Code& code)
+ : code_(code) {
srdjan 2015/11/10 19:08:51 One line
Cutch 2015/11/10 19:12:21 Done.
+ ASSERT(!code_.IsNull());
+}
+
+
+uword CodeDescriptor::Entry() const {
+ return code_.EntryPoint();
+}
+
+
+uword CodeDescriptor::Size() const {
+ return code_.Size();
+}
+
+
+int64_t CodeDescriptor::CompileTimestamp() const {
+ return code_.compile_timestamp();
+}
+
+
+CodeLookupTable::CodeLookupTable(Thread* thread) {
+ Build(thread);
+}
+
+
+class CodeLookupTableBuilder : public ObjectVisitor {
+ public:
+ CodeLookupTableBuilder(Isolate* isolate, CodeLookupTable* table)
+ : ObjectVisitor(isolate),
+ table_(table) {
+ ASSERT(table_ != NULL);
+ }
+
+ ~CodeLookupTableBuilder() {
+ }
+
+ void VisitObject(RawObject* raw_obj) {
+ uword tags = raw_obj->ptr()->tags_;
+ if (RawObject::ClassIdTag::decode(tags) == kCodeCid) {
+ RawCode* raw_code = reinterpret_cast<RawCode*>(raw_obj);
+ const Code& code = Code::Handle(raw_code);
+ ASSERT(!code.IsNull());
+ const Instructions& instructions =
+ Instructions::Handle(code.instructions());
+ ASSERT(!instructions.IsNull());
+ table_->Add(code);
+ }
+ }
+
+ private:
+ CodeLookupTable* table_;
+};
+
+
+void CodeLookupTable::Build(Thread* thread) {
+ ASSERT(thread != NULL);
+ Isolate* isolate = thread->isolate();
+ ASSERT(isolate != NULL);
+ Isolate* vm_isolate = Dart::vm_isolate();
+ ASSERT(vm_isolate != NULL);
+
+ // Clear.
+ code_objects_.Clear();
+
+ // Add all found Code objects.
+ CodeLookupTableBuilder cltb(isolate, this);
+ vm_isolate->heap()->IterateOldObjects(&cltb);
+ isolate->heap()->IterateOldObjects(&cltb);
+
+ // Sort by entry.
+ code_objects_.Sort(CodeDescriptor::Compare);
+
+#if defined(DEBUG)
+ if (length() <= 1) {
+ return;
+ }
+ // Sanity check that we don't have duplicate entries.
+ for (intptr_t i = 0; i < length() - 1; i++) {
+ const CodeDescriptor* a = At(i);
+ const CodeDescriptor* b = At(i + 1);
+ ASSERT(a->Entry() < b->Entry());
+ ASSERT(FindCode(0) == NULL);
rmacnak 2015/11/10 18:53:13 This can go out of the loop
Cutch 2015/11/10 19:12:21 Done.
+ ASSERT(FindCode(~0) == NULL);
+ ASSERT(FindCode(a->Entry()) == a);
+ ASSERT(FindCode(b->Entry()) == b);
+ ASSERT(FindCode(a->Entry() + a->Size() - 1) == a);
+ ASSERT(FindCode(b->Entry() + b->Size() - 1) == b);
+ }
+#endif
+}
+
+
+void CodeLookupTable::Add(const Code& code) {
+ ASSERT(!code.IsNull());
+ CodeDescriptor* cd = new CodeDescriptor(code);
+ code_objects_.Add(cd);
+}
+
+
+const CodeDescriptor* CodeLookupTable::FindCode(uword pc) const {
+ // std::upper_bound.
srdjan 2015/11/10 19:08:51 Why this comment?
Cutch 2015/11/10 19:12:21 It's the name of the algorithm from C++ <algorithm
+ intptr_t first = 0;
+ intptr_t count = length();
+ while (count > 0) {
+ intptr_t current = first;
+ intptr_t step = count / 2;
+ current += step;
+ const CodeDescriptor* cd = At(current);
+ if (!(pc < cd->Entry())) {
srdjan 2015/11/10 19:08:51 Either pc >= cd->Entry() or if (pc<cd->Entry()) {
Cutch 2015/11/10 19:12:21 Done.
+ first = ++current;
+ count -= step + 1;
+ } else {
+ count = step;
+ }
+ }
+ // First points to the first code object whose entry is greater than PC.
+ // That means the code object we need to check is first - 1.
+ if (first == 0) {
+ return NULL;
+ }
+ first--;
+ ASSERT(first >= 0);
+ ASSERT(first < length());
+ const CodeDescriptor* cd = At(first);
+ if (cd->Contains(pc)) {
+ return cd;
+ }
+ return NULL;
+}
+
+
ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer(
SampleFilter* filter) {
ASSERT(filter != NULL);
@@ -1084,13 +1217,15 @@ ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer(
// Did not pass filter.
continue;
}
- buffer->Add(BuildProcessedSample(sample));
+ buffer->Add(BuildProcessedSample(sample, buffer->code_lookup_table()));
}
return buffer;
}
-ProcessedSample* SampleBuffer::BuildProcessedSample(Sample* sample) {
+ProcessedSample* SampleBuffer::BuildProcessedSample(
+ Sample* sample,
+ const CodeLookupTable& clt) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -1121,9 +1256,7 @@ ProcessedSample* SampleBuffer::BuildProcessedSample(Sample* sample) {
}
if (!sample->exit_frame_sample()) {
- Isolate* vm_isolate = Dart::vm_isolate();
- processed_sample->FixupCaller(thread,
- vm_isolate,
+ processed_sample->FixupCaller(clt,
sample->pc_marker(),
sample->GetStackBuffer());
}
@@ -1163,31 +1296,29 @@ ProcessedSample::ProcessedSample()
}
-void ProcessedSample::FixupCaller(Thread* thread,
- Isolate* vm_isolate,
+void ProcessedSample::FixupCaller(const CodeLookupTable& clt,
uword pc_marker,
uword* stack_buffer) {
- REUSABLE_CODE_HANDLESCOPE(thread);
- // Lookup code object for leaf frame.
- Code& code = reused_code_handle.Handle();
- code = FindCodeForPC(thread->isolate(), vm_isolate, At(0));
- if (code.IsNull()) {
+ const CodeDescriptor* cd = clt.FindCode(At(0));
+ if (cd == NULL) {
+ // No Dart code.
return;
}
- if (code.compile_timestamp() > timestamp()) {
+ if (cd->CompileTimestamp() > timestamp()) {
// Code compiled after sample. Ignore.
return;
}
- CheckForMissingDartFrame(
- thread->isolate(), vm_isolate, code, pc_marker, stack_buffer);
+ CheckForMissingDartFrame(clt, cd, pc_marker, stack_buffer);
}
-void ProcessedSample::CheckForMissingDartFrame(Isolate* isolate,
- Isolate* vm_isolate,
- const Code& code,
+void ProcessedSample::CheckForMissingDartFrame(const CodeLookupTable& clt,
+ const CodeDescriptor* cd,
uword pc_marker,
uword* stack_buffer) {
+ ASSERT(cd != NULL);
+ const Code& code = Code::Handle(cd->code());
+ ASSERT(!code.IsNull());
// Some stubs (and intrinsics) do not push a frame onto the stack leaving
// the frame pointer in the caller.
//
@@ -1204,7 +1335,6 @@ void ProcessedSample::CheckForMissingDartFrame(Isolate* isolate,
// the PC marker. We can use the PC marker to insert DART3 into the stack
// so that it will correctly be: STUB, DART3, DART2, DART1. Note the
// inserted PC may not accurately reflect the true return address into DART3.
- ASSERT(!code.IsNull());
// The pc marker is our current best guess of a return address.
uword return_address = pc_marker;
@@ -1226,8 +1356,8 @@ void ProcessedSample::CheckForMissingDartFrame(Isolate* isolate,
}
}
- if (!ContainedInDartCodeHeaps(isolate, vm_isolate, return_address)) {
- // return address is not from the Dart heap. Do not insert.
+ if (clt.FindCode(return_address) == NULL) {
+ // Return address is not from a Dart code object. Do not insert.
return;
}
@@ -1237,32 +1367,9 @@ void ProcessedSample::CheckForMissingDartFrame(Isolate* isolate,
}
-RawCode* ProcessedSample::FindCodeForPC(Isolate* isolate,
- Isolate* vm_isolate,
- uword pc) {
- // Check current isolate for pc.
- if (isolate->heap()->CodeContains(pc)) {
- return Code::LookupCode(pc);
- }
-
- // Check VM isolate for pc.
- if (vm_isolate->heap()->CodeContains(pc)) {
- return Code::LookupCodeInVmIsolate(pc);
- }
-
- return Code::null();
-}
-
-
-bool ProcessedSample::ContainedInDartCodeHeaps(Isolate* isolate,
- Isolate* vm_isolate,
- uword pc) {
- return vm_isolate->heap()->CodeContains(pc)
- || isolate->heap()->CodeContains(pc);
-}
-
-
-ProcessedSampleBuffer::ProcessedSampleBuffer() {
+ProcessedSampleBuffer::ProcessedSampleBuffer()
+ : code_lookup_table_(new CodeLookupTable(Thread::Current())) {
+ ASSERT(code_lookup_table_ != NULL);
}
} // namespace dart
« no previous file with comments | « runtime/vm/profiler.h ('k') | runtime/vm/profiler_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698