Skip to content

Commit 48f31bd

Browse files
psmarshallBethGriggs
authored andcommittedOct 12, 2018
deps: V8: backport 20 CPU profiler commits from upstream
[cpu-profiler] Fix bugs and add tests for JITLineInfoTable https://chromium.googlesource.com/v8/v8/+/4feb5ce7fd5ef8c933f3f5dff2eca1173f85c1e9 [cpu-profiler] Fix incorrect line number calculation. https://chromium.googlesource.com/v8/v8/+/ddb2856f39632f9e9f623d3cdb4600e636172031 [cpu-profiler] Use std::unordered_map for hashmaps. https://chromium.googlesource.com/v8/v8/+/35985ce6abc80b85264fe3b87b246fed5f1806e6 [cpu-profiler] Do not store CodeEntries between profiling sessions. https://chromium.googlesource.com/v8/v8.git/+/8ec48b2117b8092c4956f1ee11a0c85bec3ba1f8 [cpu-profiler] Remove name_prefix field from CodeEntry https://chromium.googlesource.com/v8/v8.git/+/6f72af25fe43218b60c68129073ddcddb631566e [cpu-profiler] Extract rare used fields of CodeEntry to an optional object. https://chromium.googlesource.com/v8/v8.git/+/fcc1ebb55aab38013855834f556f6e874e0eb8b3 [profiler] Refactoring: decouple StringsStorage from Heap object. https://chromium.googlesource.com/v8/v8/+/a31320f59c911a277566d6c2fa0b0f2ac83e0748 [cpu-profiler] Add a HandleScope to limit memory consumption. https://chromium.googlesource.com/v8/v8.git/+/3e9f8a4f635e2d946651d6a4df81378266f32dc9 [cpu-profiler] Lazily create CPU profiler. https://chromium.googlesource.com/v8/v8/+/1426ea1d6d45be0b4d9476bdb5bf3f27cfe578a0 [cpu-profiler] turn several std::map's into unordered_map's. https://chromium.googlesource.com/v8/v8/+/3ed5dfb8a3cbc7aa0017bd01c2fdd6227485b8ad [cpu-profiler] Eagerly delete not used CodeEntry'es https://chromium.googlesource.com/v8/v8.git/+/c6c28f7a412a88df12055e953630a9e93cc64d49 [cpu-profiler] Move bailout reason into rare_info struct https://chromium.googlesource.com/v8/v8.git/+/29ea4d1ef5360e71c61ecf8db6a5a0a0c3391fd1 [cpu-profiler] Save space in the SourcePositionTable by using a vector. https://chromium.googlesource.com/v8/v8.git/+/1cb19f0e0a93adbac8c11bc906f951bd8098722d [cpu-profiler] Only store deopt inline frames for functions that need it https://chromium.googlesource.com/v8/v8.git/+/0bfcbdd4726920755e51dab28c18ab93e050819b [cpu-profiler] Add a new profiling mode with a more detailed call tree. https://chromium.googlesource.com/v8/v8.git/+/ecae80cdb350dde1e654c531b56f5b6c44dc8c77 [cpu-profiler] Reuse free slots in code_entries_ https://chromium.googlesource.com/v8/v8.git/+/3e1126bf15e62c433c4e9cb21316d182f691c63a [cpu-profiler] Use instruction start as the key for the CodeMap https://chromium.googlesource.com/v8/v8.git/+/ba752ea4c50713dff1e94f45a79db3ba968a8d66 [cpu-profiler] Add flag to always generate accurate line info. https://chromium.googlesource.com/v8/v8/+/56baf56790de439b3f69e887e94beb3b301ed77c [cpu-profiler] Turn on detailed line info for optimized code https://chromium.googlesource.com/v8/v8/+/84894ce6d2af7feb9e1f5574409355120887326c [cpu-profiler] Separate the flags for generating extra line information https://chromium.googlesource.com/v8/v8/+/30ff6719db441cc7ef220d449970cc169067e256 Backport-PR-URL: #21558 PR-URL: #21558 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Yang Guo <yangguo@chromium.org> Reviewed-By: Rod Vagg <rod@vagg.org>
1 parent 534bc82 commit 48f31bd

29 files changed

+852
-562
lines changed
 

‎deps/v8/include/v8-profiler.h

+17
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,16 @@ class V8_EXPORT CpuProfile {
273273
void Delete();
274274
};
275275

276+
enum CpuProfilingMode {
277+
// In the resulting CpuProfile tree, intermediate nodes in a stack trace
278+
// (from the root to a leaf) will have line numbers that point to the start
279+
// line of the function, rather than the line of the callsite of the child.
280+
kLeafNodeLineNumbers,
281+
// In the resulting CpuProfile tree, nodes are separated based on the line
282+
// number of their callsite in their parent.
283+
kCallerLineNumbers,
284+
};
285+
276286
/**
277287
* Interface for controlling CPU profiling. Instance of the
278288
* profiler can be created using v8::CpuProfiler::New method.
@@ -309,6 +319,13 @@ class V8_EXPORT CpuProfiler {
309319
* |record_samples| parameter controls whether individual samples should
310320
* be recorded in addition to the aggregated tree.
311321
*/
322+
void StartProfiling(Local<String> title, CpuProfilingMode mode,
323+
bool record_samples = false);
324+
/**
325+
* The same as StartProfiling above, but the CpuProfilingMode defaults to
326+
* kLeafNodeLineNumbers mode, which was the previous default behavior of the
327+
* profiler.
328+
*/
312329
void StartProfiling(Local<String> title, bool record_samples = false);
313330

314331
/**

‎deps/v8/include/v8-version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#define V8_MAJOR_VERSION 6
1212
#define V8_MINOR_VERSION 2
1313
#define V8_BUILD_NUMBER 414
14-
#define V8_PATCH_LEVEL 67
14+
#define V8_PATCH_LEVEL 68
1515

1616
// Use 1 for candidates and 0 otherwise.
1717
// (Boolean macro values are not supported by all preprocessors.)

‎deps/v8/src/api.cc

+9-12
Original file line numberDiff line numberDiff line change
@@ -8418,7 +8418,7 @@ HeapProfiler* Isolate::GetHeapProfiler() {
84188418

84198419
CpuProfiler* Isolate::GetCpuProfiler() {
84208420
i::CpuProfiler* cpu_profiler =
8421-
reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
8421+
reinterpret_cast<i::Isolate*>(this)->EnsureCpuProfiler();
84228422
return reinterpret_cast<CpuProfiler*>(cpu_profiler);
84238423
}
84248424

@@ -10138,15 +10138,7 @@ Local<String> CpuProfileNode::GetFunctionName() const {
1013810138
const i::CodeEntry* entry = node->entry();
1013910139
i::Handle<i::String> name =
1014010140
isolate->factory()->InternalizeUtf8String(entry->name());
10141-
if (!entry->has_name_prefix()) {
10142-
return ToApiHandle<String>(name);
10143-
} else {
10144-
// We do not expect this to fail. Change this if it does.
10145-
i::Handle<i::String> cons = isolate->factory()->NewConsString(
10146-
isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
10147-
name).ToHandleChecked();
10148-
return ToApiHandle<String>(cons);
10149-
}
10141+
return ToApiHandle<String>(name);
1015010142
}
1015110143

1015210144
int debug::Coverage::BlockData::StartOffset() const { return block_->start; }
@@ -10237,7 +10229,7 @@ const char* CpuProfileNode::GetScriptResourceNameStr() const {
1023710229
}
1023810230

1023910231
int CpuProfileNode::GetLineNumber() const {
10240-
return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
10232+
return reinterpret_cast<const i::ProfileNode*>(this)->line_number();
1024110233
}
1024210234

1024310235

@@ -10370,9 +10362,14 @@ void CpuProfiler::CollectSample() {
1037010362

1037110363
void CpuProfiler::StartProfiling(Local<String> title, bool record_samples) {
1037210364
reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10373-
*Utils::OpenHandle(*title), record_samples);
10365+
*Utils::OpenHandle(*title), record_samples, kLeafNodeLineNumbers);
1037410366
}
1037510367

10368+
void CpuProfiler::StartProfiling(Local<String> title, CpuProfilingMode mode,
10369+
bool record_samples) {
10370+
reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10371+
*Utils::OpenHandle(*title), record_samples, mode);
10372+
}
1037610373

1037710374
CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
1037810375
return reinterpret_cast<CpuProfile*>(

‎deps/v8/src/code-events.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class CodeEventListener {
101101
virtual void GetterCallbackEvent(Name* name, Address entry_point) = 0;
102102
virtual void SetterCallbackEvent(Name* name, Address entry_point) = 0;
103103
virtual void RegExpCodeCreateEvent(AbstractCode* code, String* source) = 0;
104-
virtual void CodeMoveEvent(AbstractCode* from, Address to) = 0;
104+
virtual void CodeMoveEvent(AbstractCode* from, AbstractCode* to) = 0;
105105
virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
106106
virtual void CodeMovingGCEvent() = 0;
107107
virtual void CodeDisableOptEvent(AbstractCode* code,
@@ -163,7 +163,7 @@ class CodeEventDispatcher {
163163
void RegExpCodeCreateEvent(AbstractCode* code, String* source) {
164164
CODE_EVENT_DISPATCH(RegExpCodeCreateEvent(code, source));
165165
}
166-
void CodeMoveEvent(AbstractCode* from, Address to) {
166+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
167167
CODE_EVENT_DISPATCH(CodeMoveEvent(from, to));
168168
}
169169
void SharedFunctionInfoMoveEvent(Address from, Address to) {

‎deps/v8/src/compilation-info.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ CompilationInfo::CompilationInfo(Zone* zone, Isolate* isolate,
5151
// Collect source positions for optimized code when profiling or if debugger
5252
// is active, to be able to get more precise source positions at the price of
5353
// more memory consumption.
54-
if (isolate_->NeedsSourcePositionsForProfiling()) {
54+
if (isolate_->NeedsDetailedOptimizedCodeLineInfo()) {
5555
MarkAsSourcePositionsEnabled();
5656
}
5757
}

‎deps/v8/src/flag-definitions.h

+3
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,9 @@ DEFINE_BOOL(log_source_code, false, "Log source code.")
10821082
DEFINE_BOOL(prof, false,
10831083
"Log statistical profiling information (implies --log-code).")
10841084

1085+
DEFINE_BOOL(detailed_line_info, true,
1086+
"Always generate detailed line information for CPU profiling.")
1087+
10851088
#if defined(ANDROID)
10861089
// Phones and tablets have processors that are much slower than desktop
10871090
// and laptop computers for which current heuristics are tuned.

‎deps/v8/src/heap/mark-compact.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ class ProfilingMigrationObserver final : public MigrationObserver {
14841484
int size) final {
14851485
if (dest == CODE_SPACE || (dest == OLD_SPACE && dst->IsBytecodeArray())) {
14861486
PROFILE(heap_->isolate(),
1487-
CodeMoveEvent(AbstractCode::cast(src), dst->address()));
1487+
CodeMoveEvent(AbstractCode::cast(src), AbstractCode::cast(dst)));
14881488
}
14891489
heap_->OnMoveEvent(dst, src, size);
14901490
}

‎deps/v8/src/isolate.cc

+11-1
Original file line numberDiff line numberDiff line change
@@ -2697,7 +2697,6 @@ bool Isolate::Init(StartupDeserializer* des) {
26972697
call_descriptor_data_ =
26982698
new CallInterfaceDescriptorData[CallDescriptors::NUMBER_OF_DESCRIPTORS];
26992699
access_compiler_data_ = new AccessCompilerData();
2700-
cpu_profiler_ = new CpuProfiler(this);
27012700
heap_profiler_ = new HeapProfiler(heap());
27022701
interpreter_ = new interpreter::Interpreter(this);
27032702
compiler_dispatcher_ =
@@ -2970,6 +2969,10 @@ bool Isolate::use_optimizer() {
29702969
!is_precise_count_code_coverage() && !is_block_count_code_coverage();
29712970
}
29722971

2972+
bool Isolate::NeedsDetailedOptimizedCodeLineInfo() const {
2973+
return NeedsSourcePositionsForProfiling() || FLAG_detailed_line_info;
2974+
}
2975+
29732976
bool Isolate::NeedsSourcePositionsForProfiling() const {
29742977
return FLAG_trace_deopt || FLAG_trace_turbo || FLAG_trace_turbo_graph ||
29752978
FLAG_turbo_profiling || FLAG_perf_prof || is_profiling() ||
@@ -3694,6 +3697,13 @@ void Isolate::PrintWithTimestamp(const char* format, ...) {
36943697
va_end(arguments);
36953698
}
36963699

3700+
CpuProfiler* Isolate::EnsureCpuProfiler() {
3701+
if (!cpu_profiler_) {
3702+
cpu_profiler_ = new CpuProfiler(this);
3703+
}
3704+
return cpu_profiler_;
3705+
}
3706+
36973707
bool StackLimitCheck::JsHasOverflowed(uintptr_t gap) const {
36983708
StackGuard* stack_guard = isolate_->stack_guard();
36993709
#ifdef USE_SIMULATOR

‎deps/v8/src/isolate.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,8 @@ class Isolate {
10191019

10201020
bool NeedsSourcePositionsForProfiling() const;
10211021

1022+
bool NeedsDetailedOptimizedCodeLineInfo() const;
1023+
10221024
bool is_best_effort_code_coverage() const {
10231025
return code_coverage_mode() == debug::Coverage::kBestEffort;
10241026
}
@@ -1449,7 +1451,7 @@ class Isolate {
14491451

14501452
// TODO(alph): Remove along with the deprecated GetCpuProfiler().
14511453
friend v8::CpuProfiler* v8::Isolate::GetCpuProfiler();
1452-
CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
1454+
CpuProfiler* EnsureCpuProfiler();
14531455

14541456
base::Atomic32 id_;
14551457
EntryStackItem* entry_stack_;

‎deps/v8/src/log.cc

+11-37
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "src/log-utils.h"
2323
#include "src/macro-assembler.h"
2424
#include "src/perf-jit.h"
25-
#include "src/profiler/profiler-listener.h"
2625
#include "src/profiler/tick-sample.h"
2726
#include "src/runtime-profiler.h"
2827
#include "src/source-position-table.h"
@@ -218,7 +217,7 @@ class PerfBasicLogger : public CodeEventLogger {
218217
PerfBasicLogger();
219218
~PerfBasicLogger() override;
220219

221-
void CodeMoveEvent(AbstractCode* from, Address to) override {}
220+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override {}
222221
void CodeDisableOptEvent(AbstractCode* code,
223222
SharedFunctionInfo* shared) override {}
224223

@@ -287,7 +286,7 @@ class LowLevelLogger : public CodeEventLogger {
287286
explicit LowLevelLogger(const char* file_name);
288287
~LowLevelLogger() override;
289288

290-
void CodeMoveEvent(AbstractCode* from, Address to) override;
289+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override;
291290
void CodeDisableOptEvent(AbstractCode* code,
292291
SharedFunctionInfo* shared) override {}
293292
void SnapshotPositionEvent(HeapObject* obj, int pos);
@@ -393,11 +392,10 @@ void LowLevelLogger::LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*,
393392
code->instruction_size());
394393
}
395394

396-
void LowLevelLogger::CodeMoveEvent(AbstractCode* from, Address to) {
395+
void LowLevelLogger::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
397396
CodeMoveStruct event;
398397
event.from_address = from->instruction_start();
399-
size_t header_size = from->instruction_start() - from->address();
400-
event.to_address = to + header_size;
398+
event.to_address = to->instruction_start();
401399
LogWriteStruct(event);
402400
}
403401

@@ -419,7 +417,7 @@ class JitLogger : public CodeEventLogger {
419417
public:
420418
explicit JitLogger(JitCodeEventHandler code_event_handler);
421419

422-
void CodeMoveEvent(AbstractCode* from, Address to) override;
420+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override;
423421
void CodeDisableOptEvent(AbstractCode* code,
424422
SharedFunctionInfo* shared) override {}
425423
void AddCodeLinePosInfoEvent(void* jit_handler_data, int pc_offset,
@@ -460,19 +458,14 @@ void JitLogger::LogRecordedBuffer(AbstractCode* code,
460458
code_event_handler_(&event);
461459
}
462460

463-
void JitLogger::CodeMoveEvent(AbstractCode* from, Address to) {
461+
void JitLogger::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
464462
base::LockGuard<base::Mutex> guard(&logger_mutex_);
465463

466464
JitCodeEvent event;
467465
event.type = JitCodeEvent::CODE_MOVED;
468-
event.code_start = from->instruction_start();
466+
event.code_start = reinterpret_cast<void*>(from->instruction_start());
469467
event.code_len = from->instruction_size();
470-
471-
// Calculate the header size.
472-
const size_t header_size = from->instruction_start() - from->address();
473-
474-
// Calculate the new start address of the instructions.
475-
event.new_code_start = to + header_size;
468+
event.new_code_start = reinterpret_cast<void*>(to->instruction_start());
476469

477470
code_event_handler_(&event);
478471
}
@@ -739,7 +732,6 @@ Logger::Logger(Isolate* isolate)
739732
perf_jit_logger_(NULL),
740733
ll_logger_(NULL),
741734
jit_logger_(NULL),
742-
listeners_(5),
743735
is_initialized_(false) {}
744736

745737
Logger::~Logger() {
@@ -1297,9 +1289,10 @@ void Logger::RegExpCodeCreateEvent(AbstractCode* code, String* source) {
12971289
msg.WriteToLogFile();
12981290
}
12991291

1300-
void Logger::CodeMoveEvent(AbstractCode* from, Address to) {
1292+
void Logger::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
13011293
if (!is_logging_code_events()) return;
1302-
MoveEventInternal(CodeEventListener::CODE_MOVE_EVENT, from->address(), to);
1294+
MoveEventInternal(CodeEventListener::CODE_MOVE_EVENT, from->address(),
1295+
to->address());
13031296
}
13041297

13051298
void Logger::CodeLinePosInfoRecordEvent(AbstractCode* code,
@@ -1876,8 +1869,6 @@ bool Logger::SetUp(Isolate* isolate) {
18761869
profiler_->Engage();
18771870
}
18781871

1879-
profiler_listener_.reset();
1880-
18811872
if (is_logging_) {
18821873
addCodeEventListener(this);
18831874
}
@@ -1905,19 +1896,6 @@ void Logger::SetCodeEventHandler(uint32_t options,
19051896
}
19061897
}
19071898

1908-
void Logger::SetUpProfilerListener() {
1909-
if (!is_initialized_) return;
1910-
if (profiler_listener_.get() == nullptr) {
1911-
profiler_listener_.reset(new ProfilerListener(isolate_));
1912-
}
1913-
addCodeEventListener(profiler_listener_.get());
1914-
}
1915-
1916-
void Logger::TearDownProfilerListener() {
1917-
if (profiler_listener_->HasObservers()) return;
1918-
removeCodeEventListener(profiler_listener_.get());
1919-
}
1920-
19211899
sampler::Sampler* Logger::sampler() {
19221900
return ticker_;
19231901
}
@@ -1961,10 +1939,6 @@ FILE* Logger::TearDown() {
19611939
jit_logger_ = NULL;
19621940
}
19631941

1964-
if (profiler_listener_.get() != nullptr) {
1965-
removeCodeEventListener(profiler_listener_.get());
1966-
}
1967-
19681942
return log_->Close();
19691943
}
19701944

‎deps/v8/src/log.h

+1-13
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ class LowLevelLogger;
7474
class PerfBasicLogger;
7575
class PerfJitLogger;
7676
class Profiler;
77-
class ProfilerListener;
7877
class RuntimeCallTimer;
7978
class Ticker;
8079

@@ -102,16 +101,8 @@ class Logger : public CodeEventListener {
102101
void SetCodeEventHandler(uint32_t options,
103102
JitCodeEventHandler event_handler);
104103

105-
// Sets up ProfilerListener.
106-
void SetUpProfilerListener();
107-
108-
// Tear down ProfilerListener if it has no observers.
109-
void TearDownProfilerListener();
110-
111104
sampler::Sampler* sampler();
112105

113-
ProfilerListener* profiler_listener() { return profiler_listener_.get(); }
114-
115106
// Frees resources acquired in SetUp.
116107
// When a temporary file is used for the log, returns its stream descriptor,
117108
// leaving the file open.
@@ -177,7 +168,7 @@ class Logger : public CodeEventListener {
177168
// Emits a code create event for a RegExp.
178169
void RegExpCodeCreateEvent(AbstractCode* code, String* source);
179170
// Emits a code move event.
180-
void CodeMoveEvent(AbstractCode* from, Address to);
171+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to);
181172
// Emits a code line info record event.
182173
void CodeLinePosInfoRecordEvent(AbstractCode* code,
183174
ByteArray* source_position_table);
@@ -316,8 +307,6 @@ class Logger : public CodeEventListener {
316307
PerfJitLogger* perf_jit_logger_;
317308
LowLevelLogger* ll_logger_;
318309
JitLogger* jit_logger_;
319-
std::unique_ptr<ProfilerListener> profiler_listener_;
320-
List<CodeEventListener*> listeners_;
321310
std::set<int> logged_source_code_;
322311
uint32_t next_source_info_id_ = 0;
323312

@@ -400,7 +389,6 @@ class CodeEventLogger : public CodeEventListener {
400389
NameBuffer* name_buffer_;
401390
};
402391

403-
404392
} // namespace internal
405393
} // namespace v8
406394

‎deps/v8/src/perf-jit.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ void PerfJitLogger::LogWriteUnwindingInfo(Code* code) {
376376
LogWriteBytes(padding_bytes, static_cast<int>(padding_size));
377377
}
378378

379-
void PerfJitLogger::CodeMoveEvent(AbstractCode* from, Address to) {
379+
void PerfJitLogger::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
380380
// Code relocation not supported.
381381
UNREACHABLE();
382382
}

‎deps/v8/src/perf-jit.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class PerfJitLogger : public CodeEventLogger {
4141
PerfJitLogger();
4242
virtual ~PerfJitLogger();
4343

44-
void CodeMoveEvent(AbstractCode* from, Address to) override;
44+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override;
4545
void CodeDisableOptEvent(AbstractCode* code,
4646
SharedFunctionInfo* shared) override {}
4747

@@ -113,7 +113,7 @@ class PerfJitLogger : public CodeEventLogger {
113113
// PerfJitLogger is only implemented on Linux
114114
class PerfJitLogger : public CodeEventLogger {
115115
public:
116-
void CodeMoveEvent(AbstractCode* from, Address to) override {
116+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override {
117117
UNIMPLEMENTED();
118118
}
119119

‎deps/v8/src/profiler/cpu-profiler-inl.h

+11-7
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,35 @@ namespace v8 {
1616
namespace internal {
1717

1818
void CodeCreateEventRecord::UpdateCodeMap(CodeMap* code_map) {
19-
code_map->AddCode(start, entry, size);
19+
code_map->AddCode(instruction_start, entry, instruction_size);
2020
}
2121

2222

2323
void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
24-
code_map->MoveCode(from, to);
24+
code_map->MoveCode(from_instruction_start, to_instruction_start);
2525
}
2626

2727

2828
void CodeDisableOptEventRecord::UpdateCodeMap(CodeMap* code_map) {
29-
CodeEntry* entry = code_map->FindEntry(start);
30-
if (entry != NULL) {
29+
CodeEntry* entry = code_map->FindEntry(instruction_start);
30+
if (entry != nullptr) {
3131
entry->set_bailout_reason(bailout_reason);
3232
}
3333
}
3434

3535

3636
void CodeDeoptEventRecord::UpdateCodeMap(CodeMap* code_map) {
37-
CodeEntry* entry = code_map->FindEntry(start);
38-
if (entry != NULL) entry->set_deopt_info(deopt_reason, deopt_id);
37+
CodeEntry* entry = code_map->FindEntry(instruction_start);
38+
if (entry == nullptr) return;
39+
std::vector<CpuProfileDeoptFrame> frames_vector(
40+
deopt_frames, deopt_frames + deopt_frame_count);
41+
entry->set_deopt_info(deopt_reason, deopt_id, std::move(frames_vector));
42+
delete[] deopt_frames;
3943
}
4044

4145

4246
void ReportBuiltinEventRecord::UpdateCodeMap(CodeMap* code_map) {
43-
CodeEntry* entry = code_map->FindEntry(start);
47+
CodeEntry* entry = code_map->FindEntry(instruction_start);
4448
if (!entry) {
4549
// Code objects for builtins should already have been added to the map but
4650
// some of them have been filtered out by CpuProfiler.

‎deps/v8/src/profiler/cpu-profiler.cc

+28-22
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
#include "src/profiler/cpu-profiler.h"
66

7+
#include <unordered_map>
8+
#include <utility>
9+
10+
#include "src/base/lazy-instance.h"
11+
#include "src/base/platform/mutex.h"
12+
#include "src/base/template-utils.h"
713
#include "src/debug/debug.h"
814
#include "src/deoptimizer.h"
915
#include "src/frames-inl.h"
@@ -275,20 +281,19 @@ void CpuProfiler::set_sampling_interval(base::TimeDelta value) {
275281
void CpuProfiler::ResetProfiles() {
276282
profiles_.reset(new CpuProfilesCollection(isolate_));
277283
profiles_->set_cpu_profiler(this);
284+
profiler_listener_.reset();
285+
generator_.reset();
278286
}
279287

280288
void CpuProfiler::CreateEntriesForRuntimeCallStats() {
281-
static_entries_.clear();
282289
RuntimeCallStats* rcs = isolate_->counters()->runtime_call_stats();
283290
CodeMap* code_map = generator_->code_map();
284291
for (int i = 0; i < RuntimeCallStats::counters_count; ++i) {
285292
RuntimeCallCounter* counter = &(rcs->*(RuntimeCallStats::counters[i]));
286293
DCHECK(counter->name());
287-
std::unique_ptr<CodeEntry> entry(
288-
new CodeEntry(CodeEventListener::FUNCTION_TAG, counter->name(),
289-
CodeEntry::kEmptyNamePrefix, "native V8Runtime"));
290-
code_map->AddCode(reinterpret_cast<Address>(counter), entry.get(), 1);
291-
static_entries_.push_back(std::move(entry));
294+
auto entry = new CodeEntry(CodeEventListener::FUNCTION_TAG, counter->name(),
295+
"native V8Runtime");
296+
code_map->AddCode(reinterpret_cast<Address>(counter), entry, 1);
292297
}
293298
}
294299

@@ -298,20 +303,20 @@ void CpuProfiler::CollectSample() {
298303
}
299304
}
300305

301-
void CpuProfiler::StartProfiling(const char* title, bool record_samples) {
302-
if (profiles_->StartProfiling(title, record_samples)) {
306+
void CpuProfiler::StartProfiling(const char* title, bool record_samples,
307+
ProfilingMode mode) {
308+
if (profiles_->StartProfiling(title, record_samples, mode)) {
303309
TRACE_EVENT0("v8", "CpuProfiler::StartProfiling");
304310
StartProcessorIfNotStarted();
305311
}
306312
}
307313

308-
309-
void CpuProfiler::StartProfiling(String* title, bool record_samples) {
310-
StartProfiling(profiles_->GetName(title), record_samples);
314+
void CpuProfiler::StartProfiling(String* title, bool record_samples,
315+
ProfilingMode mode) {
316+
StartProfiling(profiles_->GetName(title), record_samples, mode);
311317
isolate_->debug()->feature_tracker()->Track(DebugFeatureTracker::kProfiler);
312318
}
313319

314-
315320
void CpuProfiler::StartProcessorIfNotStarted() {
316321
if (processor_) {
317322
processor_->AddCurrentStack(isolate_);
@@ -321,13 +326,17 @@ void CpuProfiler::StartProcessorIfNotStarted() {
321326
// Disable logging when using the new implementation.
322327
saved_is_logging_ = logger->is_logging_;
323328
logger->is_logging_ = false;
324-
generator_.reset(new ProfileGenerator(profiles_.get()));
329+
if (!generator_) {
330+
generator_.reset(new ProfileGenerator(profiles_.get()));
331+
CreateEntriesForRuntimeCallStats();
332+
}
325333
processor_.reset(new ProfilerEventsProcessor(isolate_, generator_.get(),
326334
sampling_interval_));
327-
CreateEntriesForRuntimeCallStats();
328-
logger->SetUpProfilerListener();
329-
ProfilerListener* profiler_listener = logger->profiler_listener();
330-
profiler_listener->AddObserver(this);
335+
if (!profiler_listener_) {
336+
profiler_listener_.reset(new ProfilerListener(isolate_, this));
337+
}
338+
logger->addCodeEventListener(profiler_listener_.get());
339+
331340
is_profiling_ = true;
332341
isolate_->set_is_profiling(true);
333342
// Enumerate stuff we already have in the heap.
@@ -362,12 +371,9 @@ void CpuProfiler::StopProcessor() {
362371
Logger* logger = isolate_->logger();
363372
is_profiling_ = false;
364373
isolate_->set_is_profiling(false);
365-
ProfilerListener* profiler_listener = logger->profiler_listener();
366-
profiler_listener->RemoveObserver(this);
374+
logger->removeCodeEventListener(profiler_listener_.get());
367375
processor_->StopSynchronously();
368-
logger->TearDownProfilerListener();
369376
processor_.reset();
370-
generator_.reset();
371377
logger->is_logging_ = saved_is_logging_;
372378
}
373379

@@ -379,7 +385,7 @@ void CpuProfiler::LogBuiltins() {
379385
CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN);
380386
ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_;
381387
Builtins::Name id = static_cast<Builtins::Name>(i);
382-
rec->start = builtins->builtin(id)->address();
388+
rec->instruction_start = builtins->builtin(id)->instruction_start();
383389
rec->builtin_id = id;
384390
processor_->Enqueue(evt_rec);
385391
}

‎deps/v8/src/profiler/cpu-profiler.h

+19-11
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,26 @@ class CodeEventRecord {
5353

5454
class CodeCreateEventRecord : public CodeEventRecord {
5555
public:
56-
Address start;
56+
Address instruction_start;
5757
CodeEntry* entry;
58-
unsigned size;
58+
unsigned instruction_size;
5959

6060
INLINE(void UpdateCodeMap(CodeMap* code_map));
6161
};
6262

6363

6464
class CodeMoveEventRecord : public CodeEventRecord {
6565
public:
66-
Address from;
67-
Address to;
66+
Address from_instruction_start;
67+
Address to_instruction_start;
6868

6969
INLINE(void UpdateCodeMap(CodeMap* code_map));
7070
};
7171

7272

7373
class CodeDisableOptEventRecord : public CodeEventRecord {
7474
public:
75-
Address start;
75+
Address instruction_start;
7676
const char* bailout_reason;
7777

7878
INLINE(void UpdateCodeMap(CodeMap* code_map));
@@ -81,19 +81,21 @@ class CodeDisableOptEventRecord : public CodeEventRecord {
8181

8282
class CodeDeoptEventRecord : public CodeEventRecord {
8383
public:
84-
Address start;
84+
Address instruction_start;
8585
const char* deopt_reason;
8686
int deopt_id;
8787
void* pc;
8888
int fp_to_sp_delta;
89+
CpuProfileDeoptFrame* deopt_frames;
90+
int deopt_frame_count;
8991

9092
INLINE(void UpdateCodeMap(CodeMap* code_map));
9193
};
9294

9395

9496
class ReportBuiltinEventRecord : public CodeEventRecord {
9597
public:
96-
Address start;
98+
Address instruction_start;
9799
Builtins::Name builtin_id;
98100

99101
INLINE(void UpdateCodeMap(CodeMap* code_map));
@@ -195,10 +197,13 @@ class CpuProfiler : public CodeEventObserver {
195197

196198
~CpuProfiler() override;
197199

200+
typedef v8::CpuProfilingMode ProfilingMode;
201+
198202
void set_sampling_interval(base::TimeDelta value);
199203
void CollectSample();
200-
void StartProfiling(const char* title, bool record_samples = false);
201-
void StartProfiling(String* title, bool record_samples);
204+
void StartProfiling(const char* title, bool record_samples = false,
205+
ProfilingMode mode = ProfilingMode::kLeafNodeLineNumbers);
206+
void StartProfiling(String* title, bool record_samples, ProfilingMode mode);
202207
CpuProfile* StopProfiling(const char* title);
203208
CpuProfile* StopProfiling(String* title);
204209
int GetProfilesCount();
@@ -214,6 +219,10 @@ class CpuProfiler : public CodeEventObserver {
214219
ProfilerEventsProcessor* processor() const { return processor_.get(); }
215220
Isolate* isolate() const { return isolate_; }
216221

222+
ProfilerListener* profiler_listener_for_test() {
223+
return profiler_listener_.get();
224+
}
225+
217226
private:
218227
void StartProcessorIfNotStarted();
219228
void StopProcessorIfLastProfile(const char* title);
@@ -227,7 +236,7 @@ class CpuProfiler : public CodeEventObserver {
227236
std::unique_ptr<CpuProfilesCollection> profiles_;
228237
std::unique_ptr<ProfileGenerator> generator_;
229238
std::unique_ptr<ProfilerEventsProcessor> processor_;
230-
std::vector<std::unique_ptr<CodeEntry>> static_entries_;
239+
std::unique_ptr<ProfilerListener> profiler_listener_;
231240
bool saved_is_logging_;
232241
bool is_profiling_;
233242

@@ -237,5 +246,4 @@ class CpuProfiler : public CodeEventObserver {
237246
} // namespace internal
238247
} // namespace v8
239248

240-
241249
#endif // V8_PROFILER_CPU_PROFILER_H_

‎deps/v8/src/profiler/heap-profiler.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace internal {
1616

1717
HeapProfiler::HeapProfiler(Heap* heap)
1818
: ids_(new HeapObjectsMap(heap)),
19-
names_(new StringsStorage(heap)),
19+
names_(new StringsStorage(heap->HashSeed())),
2020
is_tracking_object_moves_(false),
2121
get_retainer_infos_callback_(nullptr) {}
2222

@@ -34,7 +34,7 @@ HeapProfiler::~HeapProfiler() {
3434
void HeapProfiler::DeleteAllSnapshots() {
3535
snapshots_.Iterate(DeleteHeapSnapshot);
3636
snapshots_.Clear();
37-
names_.reset(new StringsStorage(heap()));
37+
names_.reset(new StringsStorage(heap()->HashSeed()));
3838
}
3939

4040

‎deps/v8/src/profiler/profile-generator-inl.h

+14-12
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,35 @@ namespace v8 {
1111
namespace internal {
1212

1313
CodeEntry::CodeEntry(CodeEventListener::LogEventsAndTags tag, const char* name,
14-
const char* name_prefix, const char* resource_name,
15-
int line_number, int column_number,
16-
JITLineInfoTable* line_info, Address instruction_start)
14+
const char* resource_name, int line_number,
15+
int column_number,
16+
std::unique_ptr<SourcePositionTable> line_info,
17+
Address instruction_start)
1718
: bit_field_(TagField::encode(tag) |
1819
BuiltinIdField::encode(Builtins::builtin_count)),
19-
name_prefix_(name_prefix),
2020
name_(name),
2121
resource_name_(resource_name),
2222
line_number_(line_number),
2323
column_number_(column_number),
2424
script_id_(v8::UnboundScript::kNoScriptId),
2525
position_(0),
26-
bailout_reason_(kEmptyBailoutReason),
27-
deopt_reason_(kNoDeoptReason),
28-
deopt_id_(kNoDeoptimizationId),
29-
line_info_(line_info),
26+
line_info_(std::move(line_info)),
3027
instruction_start_(instruction_start) {}
3128

29+
inline CodeEntry* ProfileGenerator::FindEntry(Address address) {
30+
CodeEntry* entry = code_map_.FindEntry(address);
31+
if (entry) entry->mark_used();
32+
return entry;
33+
}
34+
3235
ProfileNode::ProfileNode(ProfileTree* tree, CodeEntry* entry,
33-
ProfileNode* parent)
36+
ProfileNode* parent, int line_number)
3437
: tree_(tree),
3538
entry_(entry),
3639
self_ticks_(0),
37-
children_(CodeEntriesMatch),
40+
line_number_(line_number),
3841
parent_(parent),
39-
id_(tree->next_node_id()),
40-
line_ticks_(LineTickMatch) {
42+
id_(tree->next_node_id()) {
4143
tree_->EnqueueNode(this);
4244
}
4345

‎deps/v8/src/profiler/profile-generator.cc

+220-147
Large diffs are not rendered by default.

‎deps/v8/src/profiler/profile-generator.h

+141-77
Large diffs are not rendered by default.

‎deps/v8/src/profiler/profiler-listener.cc

+84-92
Original file line numberDiff line numberDiff line change
@@ -13,45 +13,48 @@
1313
namespace v8 {
1414
namespace internal {
1515

16-
ProfilerListener::ProfilerListener(Isolate* isolate)
17-
: function_and_resource_names_(isolate->heap()) {}
16+
ProfilerListener::ProfilerListener(Isolate* isolate,
17+
CodeEventObserver* observer)
18+
: isolate_(isolate),
19+
observer_(observer),
20+
function_and_resource_names_(isolate->heap()->HashSeed()) {}
1821

1922
ProfilerListener::~ProfilerListener() = default;
2023

2124
void ProfilerListener::CallbackEvent(Name* name, Address entry_point) {
2225
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
2326
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
24-
rec->start = entry_point;
27+
rec->instruction_start = entry_point;
2528
rec->entry = NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name));
26-
rec->size = 1;
29+
rec->instruction_size = 1;
2730
DispatchCodeEvent(evt_rec);
2831
}
2932

3033
void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
3134
AbstractCode* code, const char* name) {
3235
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
3336
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
34-
rec->start = code->address();
37+
rec->instruction_start = code->instruction_start();
3538
rec->entry = NewCodeEntry(
36-
tag, GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
39+
tag, GetFunctionName(name),
3740
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
38-
CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
41+
CpuProfileNode::kNoColumnNumberInfo, nullptr, code->instruction_start());
3942
RecordInliningInfo(rec->entry, code);
40-
rec->size = code->ExecutableSize();
43+
rec->instruction_size = code->instruction_size();
4144
DispatchCodeEvent(evt_rec);
4245
}
4346

4447
void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
4548
AbstractCode* code, Name* name) {
4649
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
4750
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
48-
rec->start = code->address();
51+
rec->instruction_start = code->instruction_start();
4952
rec->entry = NewCodeEntry(
50-
tag, GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
53+
tag, GetFunctionName(name),
5154
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
52-
CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
55+
CpuProfileNode::kNoColumnNumberInfo, nullptr, code->instruction_start());
5356
RecordInliningInfo(rec->entry, code);
54-
rec->size = code->ExecutableSize();
57+
rec->instruction_size = code->instruction_size();
5558
DispatchCodeEvent(evt_rec);
5659
}
5760

@@ -61,15 +64,15 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
6164
Name* script_name) {
6265
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
6366
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
64-
rec->start = code->address();
67+
rec->instruction_start = code->instruction_start();
6568
rec->entry = NewCodeEntry(
66-
tag, GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix,
69+
tag, GetFunctionName(shared->DebugName()),
6770
GetName(InferScriptName(script_name, shared)),
6871
CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
69-
NULL, code->instruction_start());
72+
nullptr, code->instruction_start());
7073
RecordInliningInfo(rec->entry, code);
7174
rec->entry->FillFunctionInfo(shared);
72-
rec->size = code->ExecutableSize();
75+
rec->instruction_size = code->instruction_size();
7376
DispatchCodeEvent(evt_rec);
7477
}
7578

@@ -80,13 +83,11 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
8083
int column) {
8184
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
8285
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
83-
rec->start = abstract_code->address();
84-
JITLineInfoTable* line_table = NULL;
86+
rec->instruction_start = abstract_code->instruction_start();
87+
std::unique_ptr<SourcePositionTable> line_table;
8588
if (shared->script()->IsScript()) {
8689
Script* script = Script::cast(shared->script());
87-
line_table = new JITLineInfoTable();
88-
int offset = abstract_code->IsCode() ? Code::kHeaderSize
89-
: BytecodeArray::kHeaderSize;
90+
line_table.reset(new SourcePositionTable());
9091
for (SourcePositionTableIterator it(abstract_code->source_position_table());
9192
!it.done(); it.Advance()) {
9293
// TODO(alph,tebbi) Skipping inlined positions for now, because they might
@@ -95,48 +96,46 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
9596
continue;
9697
int position = it.source_position().ScriptOffset();
9798
int line_number = script->GetLineNumber(position) + 1;
98-
int pc_offset = it.code_offset() + offset;
99-
line_table->SetPosition(pc_offset, line_number);
99+
line_table->SetPosition(it.code_offset(), line_number);
100100
}
101101
}
102-
rec->entry = NewCodeEntry(
103-
tag, GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix,
104-
GetName(InferScriptName(script_name, shared)), line, column, line_table,
105-
abstract_code->instruction_start());
102+
rec->entry =
103+
NewCodeEntry(tag, GetFunctionName(shared->DebugName()),
104+
GetName(InferScriptName(script_name, shared)), line, column,
105+
std::move(line_table), abstract_code->instruction_start());
106106
RecordInliningInfo(rec->entry, abstract_code);
107-
RecordDeoptInlinedFrames(rec->entry, abstract_code);
108107
rec->entry->FillFunctionInfo(shared);
109-
rec->size = abstract_code->ExecutableSize();
108+
rec->instruction_size = abstract_code->instruction_size();
110109
DispatchCodeEvent(evt_rec);
111110
}
112111

113112
void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
114113
AbstractCode* code, int args_count) {
115114
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
116115
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
117-
rec->start = code->address();
116+
rec->instruction_start = code->instruction_start();
118117
rec->entry = NewCodeEntry(
119-
tag, GetName(args_count), "args_count: ", CodeEntry::kEmptyResourceName,
118+
tag, GetName(args_count), CodeEntry::kEmptyResourceName,
120119
CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
121-
NULL, code->instruction_start());
120+
nullptr, code->instruction_start());
122121
RecordInliningInfo(rec->entry, code);
123-
rec->size = code->ExecutableSize();
122+
rec->instruction_size = code->instruction_size();
124123
DispatchCodeEvent(evt_rec);
125124
}
126125

127-
void ProfilerListener::CodeMoveEvent(AbstractCode* from, Address to) {
126+
void ProfilerListener::CodeMoveEvent(AbstractCode* from, AbstractCode* to) {
128127
CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE);
129128
CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
130-
rec->from = from->address();
131-
rec->to = to;
129+
rec->from_instruction_start = from->instruction_start();
130+
rec->to_instruction_start = to->instruction_start();
132131
DispatchCodeEvent(evt_rec);
133132
}
134133

135134
void ProfilerListener::CodeDisableOptEvent(AbstractCode* code,
136135
SharedFunctionInfo* shared) {
137136
CodeEventsContainer evt_rec(CodeEventRecord::CODE_DISABLE_OPT);
138137
CodeDisableOptEventRecord* rec = &evt_rec.CodeDisableOptEventRecord_;
139-
rec->start = code->address();
138+
rec->instruction_start = code->instruction_start();
140139
rec->bailout_reason = GetBailoutReason(shared->disable_optimization_reason());
141140
DispatchCodeEvent(evt_rec);
142141
}
@@ -146,44 +145,48 @@ void ProfilerListener::CodeDeoptEvent(Code* code, DeoptKind kind, Address pc,
146145
CodeEventsContainer evt_rec(CodeEventRecord::CODE_DEOPT);
147146
CodeDeoptEventRecord* rec = &evt_rec.CodeDeoptEventRecord_;
148147
Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(code, pc);
149-
rec->start = code->address();
148+
rec->instruction_start = code->instruction_start();
150149
rec->deopt_reason = DeoptimizeReasonToString(info.deopt_reason);
151150
rec->deopt_id = info.deopt_id;
152151
rec->pc = reinterpret_cast<void*>(pc);
153152
rec->fp_to_sp_delta = fp_to_sp_delta;
153+
154+
// When a function is deoptimized, we store the deoptimized frame information
155+
// for the use of GetDeoptInfos().
156+
AttachDeoptInlinedFrames(code, rec);
154157
DispatchCodeEvent(evt_rec);
155158
}
156159

157160
void ProfilerListener::GetterCallbackEvent(Name* name, Address entry_point) {
158161
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
159162
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
160-
rec->start = entry_point;
163+
rec->instruction_start = entry_point;
161164
rec->entry =
162-
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name), "get ");
163-
rec->size = 1;
165+
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetConsName("get ", name));
166+
rec->instruction_size = 1;
164167
DispatchCodeEvent(evt_rec);
165168
}
166169

167170
void ProfilerListener::RegExpCodeCreateEvent(AbstractCode* code,
168171
String* source) {
169172
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
170173
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
171-
rec->start = code->address();
174+
rec->instruction_start = code->instruction_start();
172175
rec->entry = NewCodeEntry(
173-
CodeEventListener::REG_EXP_TAG, GetName(source), "RegExp: ",
176+
CodeEventListener::REG_EXP_TAG, GetConsName("RegExp: ", source),
174177
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
175-
CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
176-
rec->size = code->ExecutableSize();
178+
CpuProfileNode::kNoColumnNumberInfo, nullptr, code->instruction_start());
179+
rec->instruction_size = code->instruction_size();
177180
DispatchCodeEvent(evt_rec);
178181
}
179182

180183
void ProfilerListener::SetterCallbackEvent(Name* name, Address entry_point) {
181184
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
182185
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
183-
rec->start = entry_point;
186+
rec->instruction_start = entry_point;
184187
rec->entry =
185-
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name), "set ");
186-
rec->size = 1;
188+
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetConsName("set ", name));
189+
rec->instruction_size = 1;
187190
DispatchCodeEvent(evt_rec);
188191
}
189192

@@ -212,7 +215,7 @@ void ProfilerListener::RecordInliningInfo(CodeEntry* entry,
212215
DCHECK_EQ(Translation::BEGIN, opcode);
213216
it.Skip(Translation::NumberOfOperandsFor(opcode));
214217
int depth = 0;
215-
std::vector<CodeEntry*> inline_stack;
218+
std::vector<std::unique_ptr<CodeEntry>> inline_stack;
216219
while (it.HasNext() &&
217220
Translation::BEGIN !=
218221
(opcode = static_cast<Translation::Opcode>(it.Next()))) {
@@ -234,29 +237,31 @@ void ProfilerListener::RecordInliningInfo(CodeEntry* entry,
234237

235238
CodeEntry* inline_entry =
236239
new CodeEntry(entry->tag(), GetFunctionName(shared_info->DebugName()),
237-
CodeEntry::kEmptyNamePrefix, resource_name,
240+
resource_name,
238241
CpuProfileNode::kNoLineNumberInfo,
239242
CpuProfileNode::kNoColumnNumberInfo, nullptr,
240243
code->instruction_start());
241244
inline_entry->FillFunctionInfo(shared_info);
242-
inline_stack.push_back(inline_entry);
245+
inline_stack.emplace_back(inline_entry);
243246
}
244247
if (!inline_stack.empty()) {
245248
entry->AddInlineStack(pc_offset, std::move(inline_stack));
246249
}
247250
}
248251
}
249252

250-
void ProfilerListener::RecordDeoptInlinedFrames(CodeEntry* entry,
251-
AbstractCode* abstract_code) {
252-
if (abstract_code->kind() != AbstractCode::OPTIMIZED_FUNCTION) return;
253-
Handle<Code> code(abstract_code->GetCode());
254-
253+
void ProfilerListener::AttachDeoptInlinedFrames(Code* code,
254+
CodeDeoptEventRecord* rec) {
255+
int deopt_id = rec->deopt_id;
255256
SourcePosition last_position = SourcePosition::Unknown();
256257
int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_ID) |
257258
RelocInfo::ModeMask(RelocInfo::DEOPT_SCRIPT_OFFSET) |
258259
RelocInfo::ModeMask(RelocInfo::DEOPT_INLINING_ID);
259-
for (RelocIterator it(*code, mask); !it.done(); it.next()) {
260+
261+
rec->deopt_frames = nullptr;
262+
rec->deopt_frame_count = 0;
263+
264+
for (RelocIterator it(code, mask); !it.done(); it.next()) {
260265
RelocInfo* info = it.rinfo();
261266
if (info->rmode() == RelocInfo::DEOPT_SCRIPT_OFFSET) {
262267
int script_offset = static_cast<int>(info->data());
@@ -267,52 +272,39 @@ void ProfilerListener::RecordDeoptInlinedFrames(CodeEntry* entry,
267272
continue;
268273
}
269274
if (info->rmode() == RelocInfo::DEOPT_ID) {
270-
int deopt_id = static_cast<int>(info->data());
275+
if (deopt_id != static_cast<int>(info->data())) continue;
271276
DCHECK(last_position.IsKnown());
272-
std::vector<CpuProfileDeoptFrame> inlined_frames;
273-
for (SourcePositionInfo& pos_info : last_position.InliningStack(code)) {
274-
DCHECK(pos_info.position.ScriptOffset() != kNoSourcePosition);
277+
278+
// SourcePosition::InliningStack allocates a handle for the SFI of each
279+
// frame. These don't escape this function, but quickly add up. This
280+
// scope limits their lifetime.
281+
HandleScope scope(isolate_);
282+
std::vector<SourcePositionInfo> stack =
283+
last_position.InliningStack(handle(code));
284+
CpuProfileDeoptFrame* deopt_frames =
285+
new CpuProfileDeoptFrame[stack.size()];
286+
287+
int deopt_frame_count = 0;
288+
for (SourcePositionInfo& pos_info : stack) {
289+
if (pos_info.position.ScriptOffset() == kNoSourcePosition) continue;
275290
if (!pos_info.function->script()->IsScript()) continue;
276291
int script_id = Script::cast(pos_info.function->script())->id();
277292
size_t offset = static_cast<size_t>(pos_info.position.ScriptOffset());
278-
inlined_frames.push_back(CpuProfileDeoptFrame({script_id, offset}));
279-
}
280-
if (!inlined_frames.empty() &&
281-
!entry->HasDeoptInlinedFramesFor(deopt_id)) {
282-
entry->AddDeoptInlinedFrames(deopt_id, std::move(inlined_frames));
293+
deopt_frames[deopt_frame_count++] = {script_id, offset};
283294
}
295+
rec->deopt_frames = deopt_frames;
296+
rec->deopt_frame_count = deopt_frame_count;
297+
break;
284298
}
285299
}
286300
}
287301

288302
CodeEntry* ProfilerListener::NewCodeEntry(
289303
CodeEventListener::LogEventsAndTags tag, const char* name,
290-
const char* name_prefix, const char* resource_name, int line_number,
291-
int column_number, JITLineInfoTable* line_info, Address instruction_start) {
292-
std::unique_ptr<CodeEntry> code_entry = base::make_unique<CodeEntry>(
293-
tag, name, name_prefix, resource_name, line_number, column_number,
294-
line_info, instruction_start);
295-
CodeEntry* raw_code_entry = code_entry.get();
296-
code_entries_.push_back(std::move(code_entry));
297-
return raw_code_entry;
298-
}
299-
300-
void ProfilerListener::AddObserver(CodeEventObserver* observer) {
301-
base::LockGuard<base::Mutex> guard(&mutex_);
302-
if (observers_.empty()) {
303-
code_entries_.clear();
304-
}
305-
if (std::find(observers_.begin(), observers_.end(), observer) ==
306-
observers_.end()) {
307-
observers_.push_back(observer);
308-
}
309-
}
310-
311-
void ProfilerListener::RemoveObserver(CodeEventObserver* observer) {
312-
base::LockGuard<base::Mutex> guard(&mutex_);
313-
auto it = std::find(observers_.begin(), observers_.end(), observer);
314-
if (it == observers_.end()) return;
315-
observers_.erase(it);
304+
const char* resource_name, int line_number, int column_number,
305+
std::unique_ptr<SourcePositionTable> line_info, Address instruction_start) {
306+
return new CodeEntry(tag, name, resource_name, line_number, column_number,
307+
std::move(line_info), instruction_start);
316308
}
317309

318310
} // namespace internal

‎deps/v8/src/profiler/profiler-listener.h

+14-18
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef V8_PROFILER_PROFILER_LISTENER_H_
66
#define V8_PROFILER_PROFILER_LISTENER_H_
77

8+
#include <memory>
89
#include <vector>
910

1011
#include "src/code-events.h"
@@ -14,16 +15,17 @@ namespace v8 {
1415
namespace internal {
1516

1617
class CodeEventsContainer;
18+
class CodeDeoptEventRecord;
1719

1820
class CodeEventObserver {
1921
public:
2022
virtual void CodeEventHandler(const CodeEventsContainer& evt_rec) = 0;
21-
virtual ~CodeEventObserver() {}
23+
virtual ~CodeEventObserver() = default;
2224
};
2325

2426
class ProfilerListener : public CodeEventListener {
2527
public:
26-
explicit ProfilerListener(Isolate* isolate);
28+
ProfilerListener(Isolate*, CodeEventObserver*);
2729
~ProfilerListener() override;
2830

2931
void CallbackEvent(Name* name, Address entry_point) override;
@@ -40,7 +42,7 @@ class ProfilerListener : public CodeEventListener {
4042
void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
4143
AbstractCode* code, int args_count) override;
4244
void CodeMovingGCEvent() override {}
43-
void CodeMoveEvent(AbstractCode* from, Address to) override;
45+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override;
4446
void CodeDisableOptEvent(AbstractCode* code,
4547
SharedFunctionInfo* shared) override;
4648
void CodeDeoptEvent(Code* code, DeoptKind kind, Address pc,
@@ -52,45 +54,39 @@ class ProfilerListener : public CodeEventListener {
5254

5355
CodeEntry* NewCodeEntry(
5456
CodeEventListener::LogEventsAndTags tag, const char* name,
55-
const char* name_prefix = CodeEntry::kEmptyNamePrefix,
5657
const char* resource_name = CodeEntry::kEmptyResourceName,
5758
int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
5859
int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
59-
JITLineInfoTable* line_info = NULL, Address instruction_start = NULL);
60-
61-
void AddObserver(CodeEventObserver* observer);
62-
void RemoveObserver(CodeEventObserver* observer);
63-
V8_INLINE bool HasObservers() { return !observers_.empty(); }
60+
std::unique_ptr<SourcePositionTable> line_info = nullptr,
61+
Address instruction_start = NULL);
6462

6563
const char* GetName(Name* name) {
6664
return function_and_resource_names_.GetName(name);
6765
}
6866
const char* GetName(int args_count) {
6967
return function_and_resource_names_.GetName(args_count);
7068
}
69+
const char* GetConsName(const char* prefix, Name* name) {
70+
return function_and_resource_names_.GetConsName(prefix, name);
71+
}
7172
const char* GetFunctionName(Name* name) {
7273
return function_and_resource_names_.GetFunctionName(name);
7374
}
7475
const char* GetFunctionName(const char* name) {
7576
return function_and_resource_names_.GetFunctionName(name);
7677
}
77-
size_t entries_count_for_test() const { return code_entries_.size(); }
7878

7979
private:
8080
void RecordInliningInfo(CodeEntry* entry, AbstractCode* abstract_code);
81-
void RecordDeoptInlinedFrames(CodeEntry* entry, AbstractCode* abstract_code);
81+
void AttachDeoptInlinedFrames(Code* code, CodeDeoptEventRecord* rec);
8282
Name* InferScriptName(Name* name, SharedFunctionInfo* info);
8383
V8_INLINE void DispatchCodeEvent(const CodeEventsContainer& evt_rec) {
84-
base::LockGuard<base::Mutex> guard(&mutex_);
85-
for (auto observer : observers_) {
86-
observer->CodeEventHandler(evt_rec);
87-
}
84+
observer_->CodeEventHandler(evt_rec);
8885
}
8986

87+
Isolate* isolate_;
88+
CodeEventObserver* observer_;
9089
StringsStorage function_and_resource_names_;
91-
std::vector<std::unique_ptr<CodeEntry>> code_entries_;
92-
std::vector<CodeEventObserver*> observers_;
93-
base::Mutex mutex_;
9490

9591
DISALLOW_COPY_AND_ASSIGN(ProfilerListener);
9692
};

‎deps/v8/src/profiler/strings-storage.cc

+22-10
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,19 @@
66

77
#include <memory>
88

9+
#include "src/allocation.h"
910
#include "src/objects-inl.h"
1011

1112
namespace v8 {
1213
namespace internal {
1314

14-
1515
bool StringsStorage::StringsMatch(void* key1, void* key2) {
1616
return strcmp(reinterpret_cast<char*>(key1), reinterpret_cast<char*>(key2)) ==
1717
0;
1818
}
1919

20-
21-
StringsStorage::StringsStorage(Heap* heap)
22-
: hash_seed_(heap->HashSeed()), names_(StringsMatch) {}
23-
20+
StringsStorage::StringsStorage(uint32_t hash_seed)
21+
: hash_seed_(hash_seed), names_(StringsMatch) {}
2422

2523
StringsStorage::~StringsStorage() {
2624
for (base::HashMap::Entry* p = names_.Start(); p != NULL;
@@ -29,7 +27,6 @@ StringsStorage::~StringsStorage() {
2927
}
3028
}
3129

32-
3330
const char* StringsStorage::GetCopy(const char* src) {
3431
int len = static_cast<int>(strlen(src));
3532
base::HashMap::Entry* entry = GetEntry(src, len);
@@ -43,7 +40,6 @@ const char* StringsStorage::GetCopy(const char* src) {
4340
return reinterpret_cast<const char*>(entry->value);
4441
}
4542

46-
4743
const char* StringsStorage::GetFormatted(const char* format, ...) {
4844
va_list args;
4945
va_start(args, format);
@@ -52,7 +48,6 @@ const char* StringsStorage::GetFormatted(const char* format, ...) {
5248
return result;
5349
}
5450

55-
5651
const char* StringsStorage::AddOrDisposeString(char* str, int len) {
5752
base::HashMap::Entry* entry = GetEntry(str, len);
5853
if (entry->value == NULL) {
@@ -65,7 +60,6 @@ const char* StringsStorage::AddOrDisposeString(char* str, int len) {
6560
return reinterpret_cast<const char*>(entry->value);
6661
}
6762

68-
6963
const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
7064
Vector<char> str = Vector<char>::New(1024);
7165
int len = VSNPrintF(str, format, args);
@@ -76,7 +70,6 @@ const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
7670
return AddOrDisposeString(str.start(), len);
7771
}
7872

79-
8073
const char* StringsStorage::GetName(Name* name) {
8174
if (name->IsString()) {
8275
String* str = String::cast(name);
@@ -95,6 +88,25 @@ const char* StringsStorage::GetName(int index) {
9588
return GetFormatted("%d", index);
9689
}
9790

91+
const char* StringsStorage::GetConsName(const char* prefix, Name* name) {
92+
if (name->IsString()) {
93+
String* str = String::cast(name);
94+
int length = Min(kMaxNameSize, str->length());
95+
int actual_length = 0;
96+
std::unique_ptr<char[]> data = str->ToCString(
97+
DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length, &actual_length);
98+
99+
int cons_length = actual_length + static_cast<int>(strlen(prefix)) + 1;
100+
char* cons_result = NewArray<char>(cons_length);
101+
snprintf(cons_result, cons_length, "%s%s", prefix, data.get());
102+
103+
return AddOrDisposeString(cons_result, cons_length);
104+
} else if (name->IsSymbol()) {
105+
return "<symbol>";
106+
}
107+
return "";
108+
}
109+
98110
const char* StringsStorage::GetFunctionName(Name* name) {
99111
return GetName(name);
100112
}

‎deps/v8/src/profiler/strings-storage.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@
77

88
#include <stdarg.h>
99

10-
#include "src/allocation.h"
1110
#include "src/base/compiler-specific.h"
1211
#include "src/base/hashmap.h"
1312

1413
namespace v8 {
1514
namespace internal {
1615

16+
class Name;
17+
1718
// Provides a storage of strings allocated in C++ heap, to hold them
1819
// forever, even if they disappear from JS heap or external storage.
1920
class StringsStorage {
2021
public:
21-
explicit StringsStorage(Heap* heap);
22+
explicit StringsStorage(uint32_t hash_seed);
2223
~StringsStorage();
2324

2425
const char* GetCopy(const char* src);
@@ -27,6 +28,7 @@ class StringsStorage {
2728
const char* GetVFormatted(const char* format, va_list args);
2829
const char* GetName(Name* name);
2930
const char* GetName(int index);
31+
const char* GetConsName(const char* prefix, Name* name);
3032
const char* GetFunctionName(Name* name);
3133
const char* GetFunctionName(const char* name);
3234

‎deps/v8/src/snapshot/serializer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class CodeAddressMap : public CodeEventLogger {
2626
isolate_->logger()->removeCodeEventListener(this);
2727
}
2828

29-
void CodeMoveEvent(AbstractCode* from, Address to) override {
30-
address_to_name_map_.Move(from->address(), to);
29+
void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override {
30+
address_to_name_map_.Move(from->address(), to->address());
3131
}
3232

3333
void CodeDisableOptEvent(AbstractCode* code,

‎deps/v8/test/cctest/cctest.status

+3
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@
7171

7272
# BUG(5193). The cpu profiler tests are notoriously flaky.
7373
'test-cpu-profiler/CollectCpuProfile': [SKIP],
74+
'test-cpu-profiler/CollectCpuProfileCallerLineNumbers': [FAIL, PASS],
75+
'test-cpu-profiler/CollectCpuProfileSamples': [SKIP],
7476
'test-cpu-profiler/CollectDeoptEvents': [SKIP],
7577
'test-cpu-profiler/CpuProfileDeepStack': [SKIP],
78+
'test-cpu-profiler/DeoptUntrackedFunction': [SKIP],
7679
'test-cpu-profiler/FunctionApplySample': [SKIP],
7780
'test-cpu-profiler/HotDeoptNoFrameEntry': [SKIP],
7881
'test-cpu-profiler/JsNative1JsNative2JsSample': [SKIP],

‎deps/v8/test/cctest/test-cpu-profiler.cc

+151-45
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ TEST(CodeEvents) {
159159

160160
i::AbstractCode* aaa_code = CreateCode(&env);
161161
i::AbstractCode* comment_code = CreateCode(&env);
162-
i::AbstractCode* args5_code = CreateCode(&env);
163162
i::AbstractCode* comment2_code = CreateCode(&env);
164163
i::AbstractCode* moved_code = CreateCode(&env);
165164
i::AbstractCode* args3_code = CreateCode(&env);
@@ -172,9 +171,8 @@ TEST(CodeEvents) {
172171
CpuProfiler profiler(isolate, profiles, generator, processor);
173172
profiles->StartProfiling("", false);
174173
processor->Start();
175-
ProfilerListener profiler_listener(isolate);
176-
isolate->code_event_dispatcher()->AddListener(&profiler_listener);
177-
profiler_listener.AddObserver(&profiler);
174+
ProfilerListener profiler_listener(isolate, &profiler);
175+
isolate->logger()->addCodeEventListener(&profiler_listener);
178176

179177
// Enqueue code creation events.
180178
const char* aaa_str = "aaa";
@@ -183,37 +181,33 @@ TEST(CodeEvents) {
183181
*aaa_name);
184182
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment_code,
185183
"comment");
186-
profiler_listener.CodeCreateEvent(i::Logger::STUB_TAG, args5_code, 5);
187184
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment2_code,
188185
"comment2");
189-
profiler_listener.CodeMoveEvent(comment2_code, moved_code->address());
186+
profiler_listener.CodeMoveEvent(comment2_code, moved_code);
190187
profiler_listener.CodeCreateEvent(i::Logger::STUB_TAG, args3_code, 3);
191188
profiler_listener.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4);
192189

193190
// Enqueue a tick event to enable code events processing.
194-
EnqueueTickSampleEvent(processor, aaa_code->address());
191+
EnqueueTickSampleEvent(processor, aaa_code->instruction_start());
195192

196-
profiler_listener.RemoveObserver(&profiler);
197-
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
193+
isolate->logger()->removeCodeEventListener(&profiler_listener);
198194
processor->StopSynchronously();
199195

200196
// Check the state of profile generator.
201-
CodeEntry* aaa = generator->code_map()->FindEntry(aaa_code->address());
197+
CodeEntry* aaa =
198+
generator->code_map()->FindEntry(aaa_code->instruction_start());
202199
CHECK(aaa);
203200
CHECK_EQ(0, strcmp(aaa_str, aaa->name()));
204201

205202
CodeEntry* comment =
206-
generator->code_map()->FindEntry(comment_code->address());
203+
generator->code_map()->FindEntry(comment_code->instruction_start());
207204
CHECK(comment);
208205
CHECK_EQ(0, strcmp("comment", comment->name()));
209206

210-
CodeEntry* args5 = generator->code_map()->FindEntry(args5_code->address());
211-
CHECK(args5);
212-
CHECK_EQ(0, strcmp("5", args5->name()));
213-
214-
CHECK(!generator->code_map()->FindEntry(comment2_code->address()));
207+
CHECK(!generator->code_map()->FindEntry(comment2_code->instruction_start()));
215208

216-
CodeEntry* comment2 = generator->code_map()->FindEntry(moved_code->address());
209+
CodeEntry* comment2 =
210+
generator->code_map()->FindEntry(moved_code->instruction_start());
217211
CHECK(comment2);
218212
CHECK_EQ(0, strcmp("comment2", comment2->name()));
219213
}
@@ -241,9 +235,8 @@ TEST(TickEvents) {
241235
CpuProfiler profiler(isolate, profiles, generator, processor);
242236
profiles->StartProfiling("", false);
243237
processor->Start();
244-
ProfilerListener profiler_listener(isolate);
245-
isolate->code_event_dispatcher()->AddListener(&profiler_listener);
246-
profiler_listener.AddObserver(&profiler);
238+
ProfilerListener profiler_listener(isolate, &profiler);
239+
isolate->logger()->addCodeEventListener(&profiler_listener);
247240

248241
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb");
249242
profiler_listener.CodeCreateEvent(i::Logger::STUB_TAG, frame2_code, 5);
@@ -258,8 +251,7 @@ TEST(TickEvents) {
258251
frame2_code->instruction_end() - 1,
259252
frame1_code->instruction_end() - 1);
260253

261-
profiler_listener.RemoveObserver(&profiler);
262-
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
254+
isolate->logger()->removeCodeEventListener(&profiler_listener);
263255
processor->StopSynchronously();
264256
CpuProfile* profile = profiles->StopProfiling("");
265257
CHECK(profile);
@@ -314,23 +306,19 @@ TEST(Issue1398) {
314306
CpuProfiler profiler(isolate, profiles, generator, processor);
315307
profiles->StartProfiling("", false);
316308
processor->Start();
317-
ProfilerListener profiler_listener(isolate);
318-
isolate->code_event_dispatcher()->AddListener(&profiler_listener);
319-
profiler_listener.AddObserver(&profiler);
309+
ProfilerListener profiler_listener(isolate, &profiler);
320310

321311
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb");
322312

323313
v8::TickSample* sample = processor->StartTickSample();
324-
sample->pc = code->address();
325-
sample->tos = 0;
314+
sample->pc = reinterpret_cast<void*>(code->instruction_start());
315+
sample->tos = nullptr;
326316
sample->frames_count = v8::TickSample::kMaxFramesCount;
327317
for (unsigned i = 0; i < sample->frames_count; ++i) {
328-
sample->stack[i] = code->address();
318+
sample->stack[i] = reinterpret_cast<void*>(code->instruction_start());
329319
}
330320
processor->FinishTickSample();
331321

332-
profiler_listener.RemoveObserver(&profiler);
333-
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
334322
processor->StopSynchronously();
335323
CpuProfile* profile = profiles->StopProfiling("");
336324
CHECK(profile);
@@ -453,11 +441,14 @@ class ProfilerHelper {
453441
profiler_->Dispose();
454442
}
455443

444+
typedef v8::CpuProfilingMode ProfilingMode;
445+
456446
v8::CpuProfile* Run(v8::Local<v8::Function> function,
457447
v8::Local<v8::Value> argv[], int argc,
458448
unsigned min_js_samples = 0,
459449
unsigned min_external_samples = 0,
460-
bool collect_samples = false);
450+
bool collect_samples = false,
451+
ProfilingMode mode = ProfilingMode::kLeafNodeLineNumbers);
461452

462453
v8::CpuProfiler* profiler() { return profiler_; }
463454

@@ -470,11 +461,11 @@ v8::CpuProfile* ProfilerHelper::Run(v8::Local<v8::Function> function,
470461
v8::Local<v8::Value> argv[], int argc,
471462
unsigned min_js_samples,
472463
unsigned min_external_samples,
473-
bool collect_samples) {
464+
bool collect_samples, ProfilingMode mode) {
474465
v8::Local<v8::String> profile_name = v8_str("my_profile");
475466

476467
profiler_->SetSamplingInterval(100);
477-
profiler_->StartProfiling(profile_name, collect_samples);
468+
profiler_->StartProfiling(profile_name, mode, collect_samples);
478469

479470
v8::internal::CpuProfiler* iprofiler =
480471
reinterpret_cast<v8::internal::CpuProfiler*>(profiler_);
@@ -521,7 +512,6 @@ static const v8::CpuProfileNode* GetChild(v8::Local<v8::Context> context,
521512
return result;
522513
}
523514

524-
525515
static void CheckSimpleBranch(v8::Local<v8::Context> context,
526516
const v8::CpuProfileNode* node,
527517
const char* names[], int length) {
@@ -531,7 +521,6 @@ static void CheckSimpleBranch(v8::Local<v8::Context> context,
531521
}
532522
}
533523

534-
535524
static const ProfileNode* GetSimpleBranch(v8::Local<v8::Context> context,
536525
v8::CpuProfile* profile,
537526
const char* names[], int length) {
@@ -542,6 +531,43 @@ static const ProfileNode* GetSimpleBranch(v8::Local<v8::Context> context,
542531
return reinterpret_cast<const ProfileNode*>(node);
543532
}
544533

534+
struct NameLinePair {
535+
const char* name;
536+
int line_number;
537+
};
538+
539+
static const v8::CpuProfileNode* FindChild(const v8::CpuProfileNode* node,
540+
NameLinePair pair) {
541+
for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
542+
const v8::CpuProfileNode* child = node->GetChild(i);
543+
// The name and line number must match, or if the requested line number was
544+
// -1, then match any function of the same name.
545+
if (strcmp(child->GetFunctionNameStr(), pair.name) == 0 &&
546+
(child->GetLineNumber() == pair.line_number ||
547+
pair.line_number == -1)) {
548+
return child;
549+
}
550+
}
551+
return nullptr;
552+
}
553+
554+
static const v8::CpuProfileNode* GetChild(const v8::CpuProfileNode* node,
555+
NameLinePair pair) {
556+
const v8::CpuProfileNode* result = FindChild(node, pair);
557+
char buffer[100];
558+
i::SNPrintF(i::ArrayVector(buffer), "Failed to GetChild: %s:%d", pair.name, pair.line_number);
559+
if (!result) FATAL(buffer);
560+
return result;
561+
}
562+
563+
static void CheckBranch(const v8::CpuProfileNode* node, NameLinePair path[],
564+
int length) {
565+
for (int i = 0; i < length; i++) {
566+
NameLinePair pair = path[i];
567+
node = GetChild(node, pair);
568+
}
569+
}
570+
545571
static const char* cpu_profiler_test_source =
546572
"%NeverOptimizeFunction(loop);\n"
547573
"%NeverOptimizeFunction(delay);\n"
@@ -622,6 +648,40 @@ TEST(CollectCpuProfile) {
622648
profile->Delete();
623649
}
624650

651+
TEST(CollectCpuProfileCallerLineNumbers) {
652+
i::FLAG_allow_natives_syntax = true;
653+
LocalContext env;
654+
v8::HandleScope scope(env->GetIsolate());
655+
656+
CompileRun(cpu_profiler_test_source);
657+
v8::Local<v8::Function> function = GetFunction(env.local(), "start");
658+
659+
int32_t profiling_interval_ms = 200;
660+
v8::Local<v8::Value> args[] = {
661+
v8::Integer::New(env->GetIsolate(), profiling_interval_ms)};
662+
ProfilerHelper helper(env.local());
663+
helper.Run(function, args, arraysize(args), 1000, 0, false,
664+
v8::CpuProfilingMode::kCallerLineNumbers);
665+
v8::CpuProfile* profile =
666+
helper.Run(function, args, arraysize(args), 1000, 0, false,
667+
v8::CpuProfilingMode::kCallerLineNumbers);
668+
669+
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
670+
const v8::CpuProfileNode* start_node = GetChild(root, {"start", 27});
671+
const v8::CpuProfileNode* foo_node = GetChild(start_node, {"foo", 30});
672+
673+
NameLinePair bar_branch[] = {{"bar", 23}, {"delay", 19}, {"loop", 18}};
674+
CheckBranch(foo_node, bar_branch, arraysize(bar_branch));
675+
NameLinePair baz_branch[] = {{"baz", 25}, {"delay", 20}, {"loop", 18}};
676+
CheckBranch(foo_node, baz_branch, arraysize(baz_branch));
677+
NameLinePair delay_at22_branch[] = {{"delay", 22}, {"loop", 18}};
678+
CheckBranch(foo_node, delay_at22_branch, arraysize(delay_at22_branch));
679+
NameLinePair delay_at24_branch[] = {{"delay", 24}, {"loop", 18}};
680+
CheckBranch(foo_node, delay_at24_branch, arraysize(delay_at24_branch));
681+
682+
profile->Delete();
683+
}
684+
625685
static const char* hot_deopt_no_frame_entry_test_source =
626686
"%NeverOptimizeFunction(foo);\n"
627687
"%NeverOptimizeFunction(start);\n"
@@ -1087,9 +1147,7 @@ static void TickLines(bool optimize) {
10871147
CpuProfiler profiler(isolate, profiles, generator, processor);
10881148
profiles->StartProfiling("", false);
10891149
processor->Start();
1090-
ProfilerListener profiler_listener(isolate);
1091-
isolate->code_event_dispatcher()->AddListener(&profiler_listener);
1092-
profiler_listener.AddObserver(&profiler);
1150+
ProfilerListener profiler_listener(isolate, &profiler);
10931151

10941152
// Enqueue code creation events.
10951153
i::Handle<i::String> str = factory->NewStringFromAsciiChecked(func_name);
@@ -1101,8 +1159,6 @@ static void TickLines(bool optimize) {
11011159
// Enqueue a tick event to enable code events processing.
11021160
EnqueueTickSampleEvent(processor, code_address);
11031161

1104-
profiler_listener.RemoveObserver(&profiler);
1105-
isolate->code_event_dispatcher()->RemoveListener(&profiler_listener);
11061162
processor->StopSynchronously();
11071163

11081164
CpuProfile* profile = profiles->StopProfiling("");
@@ -1112,9 +1168,10 @@ static void TickLines(bool optimize) {
11121168
CodeEntry* func_entry = generator->code_map()->FindEntry(code_address);
11131169
CHECK(func_entry);
11141170
CHECK_EQ(0, strcmp(func_name, func_entry->name()));
1115-
const i::JITLineInfoTable* line_info = func_entry->line_info();
1171+
const i::SourcePositionTable* line_info = func_entry->line_info();
11161172
CHECK(line_info);
1117-
CHECK(!line_info->empty());
1173+
CHECK_NE(v8::CpuProfileNode::kNoLineNumberInfo,
1174+
line_info->GetSourceLineNumber(100));
11181175

11191176
// Check the hit source lines using V8 Public APIs.
11201177
const i::ProfileTree* tree = profile->top_down();
@@ -2293,8 +2350,57 @@ TEST(CodeEntriesMemoryLeak) {
22932350
v8::CpuProfile* profile = helper.Run(function, nullptr, 0);
22942351
profile->Delete();
22952352
}
2296-
ProfilerListener* profiler_listener =
2297-
CcTest::i_isolate()->logger()->profiler_listener();
22982353

2299-
CHECK_GE(10000ul, profiler_listener->entries_count_for_test());
2354+
i::CpuProfiler* profiler =
2355+
reinterpret_cast<i::CpuProfiler*>(helper.profiler());
2356+
CHECK(!profiler->profiler_listener_for_test());
2357+
}
2358+
2359+
TEST(SourcePositionTable) {
2360+
i::SourcePositionTable info;
2361+
2362+
// Newly created tables should return NoLineNumberInfo for any lookup.
2363+
int no_info = v8::CpuProfileNode::kNoLineNumberInfo;
2364+
CHECK_EQ(no_info, info.GetSourceLineNumber(std::numeric_limits<int>::min()));
2365+
CHECK_EQ(no_info, info.GetSourceLineNumber(0));
2366+
CHECK_EQ(no_info, info.GetSourceLineNumber(1));
2367+
CHECK_EQ(no_info, info.GetSourceLineNumber(9));
2368+
CHECK_EQ(no_info, info.GetSourceLineNumber(10));
2369+
CHECK_EQ(no_info, info.GetSourceLineNumber(11));
2370+
CHECK_EQ(no_info, info.GetSourceLineNumber(19));
2371+
CHECK_EQ(no_info, info.GetSourceLineNumber(20));
2372+
CHECK_EQ(no_info, info.GetSourceLineNumber(21));
2373+
CHECK_EQ(no_info, info.GetSourceLineNumber(100));
2374+
CHECK_EQ(no_info, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
2375+
2376+
info.SetPosition(10, 1);
2377+
info.SetPosition(20, 2);
2378+
2379+
// The only valid return values are 1 or 2 - every pc maps to a line number.
2380+
CHECK_EQ(1, info.GetSourceLineNumber(std::numeric_limits<int>::min()));
2381+
CHECK_EQ(1, info.GetSourceLineNumber(0));
2382+
CHECK_EQ(1, info.GetSourceLineNumber(1));
2383+
CHECK_EQ(1, info.GetSourceLineNumber(9));
2384+
CHECK_EQ(1, info.GetSourceLineNumber(10));
2385+
CHECK_EQ(1, info.GetSourceLineNumber(11));
2386+
CHECK_EQ(1, info.GetSourceLineNumber(19));
2387+
CHECK_EQ(2, info.GetSourceLineNumber(20));
2388+
CHECK_EQ(2, info.GetSourceLineNumber(21));
2389+
CHECK_EQ(2, info.GetSourceLineNumber(100));
2390+
CHECK_EQ(2, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
2391+
2392+
// Test SetPosition behavior.
2393+
info.SetPosition(25, 3);
2394+
CHECK_EQ(2, info.GetSourceLineNumber(21));
2395+
CHECK_EQ(3, info.GetSourceLineNumber(100));
2396+
CHECK_EQ(3, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
2397+
}
2398+
2399+
TEST(MultipleProfilers) {
2400+
std::unique_ptr<CpuProfiler> profiler1(new CpuProfiler(CcTest::i_isolate()));
2401+
std::unique_ptr<CpuProfiler> profiler2(new CpuProfiler(CcTest::i_isolate()));
2402+
profiler1->StartProfiling("1");
2403+
profiler2->StartProfiling("2");
2404+
profiler1->StopProfiling("1");
2405+
profiler2->StopProfiling("2");
23002406
}

‎deps/v8/test/cctest/test-log.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ TEST(LogVersion) {
570570
TEST(Issue539892) {
571571
class : public i::CodeEventLogger {
572572
public:
573-
void CodeMoveEvent(i::AbstractCode* from, Address to) override {}
573+
void CodeMoveEvent(i::AbstractCode* from, i::AbstractCode* to) override {}
574574
void CodeDisableOptEvent(i::AbstractCode* code,
575575
i::SharedFunctionInfo* shared) override {}
576576

‎deps/v8/test/cctest/test-profile-generator.cc

+73-42
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,25 @@ TEST(ProfileNodeFindOrAddChild) {
7272
CHECK_EQ(childNode3, node->FindOrAddChild(&entry3));
7373
}
7474

75+
TEST(ProfileNodeFindOrAddChildWithLineNumber) {
76+
CcTest::InitializeVM();
77+
ProfileTree tree(CcTest::i_isolate());
78+
ProfileNode* root = tree.root();
79+
CodeEntry a(i::CodeEventListener::FUNCTION_TAG, "a");
80+
ProfileNode* a_node = root->FindOrAddChild(&a, -1);
81+
82+
// a --(22)--> child1
83+
// --(23)--> child1
84+
85+
CodeEntry child1(i::CodeEventListener::FUNCTION_TAG, "child1");
86+
ProfileNode* child1_node = a_node->FindOrAddChild(&child1, 22);
87+
CHECK(child1_node);
88+
CHECK_EQ(child1_node, a_node->FindOrAddChild(&child1, 22));
89+
90+
ProfileNode* child2_node = a_node->FindOrAddChild(&child1, 23);
91+
CHECK(child2_node);
92+
CHECK_NE(child1_node, child2_node);
93+
}
7594

7695
TEST(ProfileNodeFindOrAddChildForSameFunction) {
7796
CcTest::InitializeVM();
@@ -180,6 +199,29 @@ TEST(ProfileTreeAddPathFromEnd) {
180199
CHECK_EQ(1u, node4->self_ticks());
181200
}
182201

202+
TEST(ProfileTreeAddPathFromEndWithLineNumbers) {
203+
CcTest::InitializeVM();
204+
CodeEntry a(i::CodeEventListener::FUNCTION_TAG, "a");
205+
CodeEntry b(i::CodeEventListener::FUNCTION_TAG, "b");
206+
CodeEntry c(i::CodeEventListener::FUNCTION_TAG, "c");
207+
ProfileTree tree(CcTest::i_isolate());
208+
ProfileTreeTestHelper helper(&tree);
209+
210+
v8::internal::ProfileStackTrace path = {{&c, 5}, {&b, 3}, {&a, 1}};
211+
tree.AddPathFromEnd(path, v8::CpuProfileNode::kNoLineNumberInfo, true,
212+
v8::CpuProfilingMode::kCallerLineNumbers);
213+
214+
ProfileNode* a_node =
215+
tree.root()->FindChild(&a, v8::CpuProfileNode::kNoLineNumberInfo);
216+
tree.Print();
217+
CHECK(a_node);
218+
219+
ProfileNode* b_node = a_node->FindChild(&b, 1);
220+
CHECK(b_node);
221+
222+
ProfileNode* c_node = b_node->FindChild(&c, 3);
223+
CHECK(c_node);
224+
}
183225

184226
TEST(ProfileTreeCalculateTotalTicks) {
185227
CcTest::InitializeVM();
@@ -278,52 +320,50 @@ static inline i::Address ToAddress(int n) {
278320

279321
TEST(CodeMapAddCode) {
280322
CodeMap code_map;
281-
CodeEntry entry1(i::CodeEventListener::FUNCTION_TAG, "aaa");
282-
CodeEntry entry2(i::CodeEventListener::FUNCTION_TAG, "bbb");
283-
CodeEntry entry3(i::CodeEventListener::FUNCTION_TAG, "ccc");
284-
CodeEntry entry4(i::CodeEventListener::FUNCTION_TAG, "ddd");
285-
code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
286-
code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
287-
code_map.AddCode(ToAddress(0x1900), &entry3, 0x50);
288-
code_map.AddCode(ToAddress(0x1950), &entry4, 0x10);
323+
CodeEntry* entry1 = new CodeEntry(i::CodeEventListener::FUNCTION_TAG, "aaa");
324+
CodeEntry* entry2 = new CodeEntry(i::CodeEventListener::FUNCTION_TAG, "bbb");
325+
CodeEntry* entry3 = new CodeEntry(i::CodeEventListener::FUNCTION_TAG, "ccc");
326+
CodeEntry* entry4 = new CodeEntry(i::CodeEventListener::FUNCTION_TAG, "ddd");
327+
code_map.AddCode(ToAddress(0x1500), entry1, 0x200);
328+
code_map.AddCode(ToAddress(0x1700), entry2, 0x100);
329+
code_map.AddCode(ToAddress(0x1900), entry3, 0x50);
330+
code_map.AddCode(ToAddress(0x1950), entry4, 0x10);
289331
CHECK(!code_map.FindEntry(0));
290332
CHECK(!code_map.FindEntry(ToAddress(0x1500 - 1)));
291-
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
292-
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100)));
293-
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1)));
294-
CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
295-
CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50)));
296-
CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1)));
333+
CHECK_EQ(entry1, code_map.FindEntry(ToAddress(0x1500)));
334+
CHECK_EQ(entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100)));
335+
CHECK_EQ(entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1)));
336+
CHECK_EQ(entry2, code_map.FindEntry(ToAddress(0x1700)));
337+
CHECK_EQ(entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50)));
338+
CHECK_EQ(entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1)));
297339
CHECK(!code_map.FindEntry(ToAddress(0x1700 + 0x100)));
298340
CHECK(!code_map.FindEntry(ToAddress(0x1900 - 1)));
299-
CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900)));
300-
CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28)));
301-
CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950)));
302-
CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7)));
303-
CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1)));
341+
CHECK_EQ(entry3, code_map.FindEntry(ToAddress(0x1900)));
342+
CHECK_EQ(entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28)));
343+
CHECK_EQ(entry4, code_map.FindEntry(ToAddress(0x1950)));
344+
CHECK_EQ(entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7)));
345+
CHECK_EQ(entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1)));
304346
CHECK(!code_map.FindEntry(ToAddress(0x1950 + 0x10)));
305347
CHECK(!code_map.FindEntry(ToAddress(0xFFFFFFFF)));
306348
}
307349

308-
309350
TEST(CodeMapMoveAndDeleteCode) {
310351
CodeMap code_map;
311-
CodeEntry entry1(i::CodeEventListener::FUNCTION_TAG, "aaa");
312-
CodeEntry entry2(i::CodeEventListener::FUNCTION_TAG, "bbb");
313-
code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
314-
code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
315-
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
316-
CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
352+
CodeEntry* entry1 = new CodeEntry(i::CodeEventListener::FUNCTION_TAG, "aaa");
353+
CodeEntry* entry2 = new CodeEntry(i::CodeEventListener::FUNCTION_TAG, "bbb");
354+
code_map.AddCode(ToAddress(0x1500), entry1, 0x200);
355+
code_map.AddCode(ToAddress(0x1700), entry2, 0x100);
356+
CHECK_EQ(entry1, code_map.FindEntry(ToAddress(0x1500)));
357+
CHECK_EQ(entry2, code_map.FindEntry(ToAddress(0x1700)));
317358
code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700)); // Deprecate bbb.
318359
CHECK(!code_map.FindEntry(ToAddress(0x1500)));
319-
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700)));
320-
CodeEntry entry3(i::CodeEventListener::FUNCTION_TAG, "ccc");
321-
code_map.AddCode(ToAddress(0x1750), &entry3, 0x100);
360+
CHECK_EQ(entry1, code_map.FindEntry(ToAddress(0x1700)));
361+
CodeEntry* entry3 = new CodeEntry(i::CodeEventListener::FUNCTION_TAG, "ccc");
362+
code_map.AddCode(ToAddress(0x1750), entry3, 0x100);
322363
CHECK(!code_map.FindEntry(ToAddress(0x1700)));
323-
CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750)));
364+
CHECK_EQ(entry3, code_map.FindEntry(ToAddress(0x1750)));
324365
}
325366

326-
327367
namespace {
328368

329369
class TestSetup {
@@ -401,10 +441,6 @@ TEST(RecordTickSample) {
401441
ProfileNode* node4 = top_down_test_helper.Walk(entry1, entry3, entry1);
402442
CHECK(node4);
403443
CHECK_EQ(entry1, node4->entry());
404-
405-
delete entry1;
406-
delete entry2;
407-
delete entry3;
408444
}
409445

410446
static void CheckNodeIds(const ProfileNode* node, unsigned* expectedId) {
@@ -466,10 +502,6 @@ TEST(SampleIds) {
466502
for (int i = 0; i < 3; i++) {
467503
CHECK_EQ(expected_id[i], profile->sample(i)->id());
468504
}
469-
470-
delete entry1;
471-
delete entry2;
472-
delete entry3;
473505
}
474506

475507

@@ -498,8 +530,6 @@ TEST(NoSamples) {
498530
CHECK_EQ(3u, nodeId - 1);
499531

500532
CHECK_EQ(0, profile->samples_count());
501-
502-
delete entry1;
503533
}
504534

505535

@@ -656,7 +686,8 @@ int GetFunctionLineNumber(CpuProfiler& profiler, LocalContext& env,
656686
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(
657687
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
658688
env->Global()->Get(env.local(), v8_str(name)).ToLocalChecked())));
659-
CodeEntry* func_entry = code_map->FindEntry(func->abstract_code()->address());
689+
CodeEntry* func_entry =
690+
code_map->FindEntry(func->abstract_code()->instruction_start());
660691
if (!func_entry)
661692
FATAL(name);
662693
return func_entry->line_number();

0 commit comments

Comments
 (0)
Please sign in to comment.