Skip to content

Commit 36f94ba

Browse files
Eliminate the need for code delete events in CPU profiler.
Events are still generated for tick processor on performance testing server to work, as soon as scripts will be updated, it will be safe to remove code delete events emitting code. [email protected] BUG=v8:1466 TEST=existing tests in test-profile-generator,test-cpu-profiler and mjsunit/tools Review URL: http://codereview.chromium.org/7864017 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@9275 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
1 parent b26c8ad commit 36f94ba

14 files changed

+124
-107
lines changed

src/cpu-profiler-inl.h

-5
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
5151
}
5252

5353

54-
void CodeDeleteEventRecord::UpdateCodeMap(CodeMap* code_map) {
55-
code_map->DeleteCode(start);
56-
}
57-
58-
5954
void SharedFunctionInfoMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
6055
code_map->MoveCode(from, to);
6156
}

src/cpu-profiler.cc

-11
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,6 @@ void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) {
137137
}
138138

139139

140-
void ProfilerEventsProcessor::CodeDeleteEvent(Address from) {
141-
CodeEventsContainer evt_rec;
142-
CodeDeleteEventRecord* rec = &evt_rec.CodeDeleteEventRecord_;
143-
rec->type = CodeEventRecord::CODE_DELETE;
144-
rec->order = ++enqueue_order_;
145-
rec->start = from;
146-
events_buffer_.Enqueue(evt_rec);
147-
}
148-
149-
150140
void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from,
151141
Address to) {
152142
CodeEventsContainer evt_rec;
@@ -425,7 +415,6 @@ void CpuProfiler::CodeMoveEvent(Address from, Address to) {
425415

426416

427417
void CpuProfiler::CodeDeleteEvent(Address from) {
428-
Isolate::Current()->cpu_profiler()->processor_->CodeDeleteEvent(from);
429418
}
430419

431420

src/cpu-profiler.h

-9
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ class TokenEnumerator;
4848
#define CODE_EVENTS_TYPE_LIST(V) \
4949
V(CODE_CREATION, CodeCreateEventRecord) \
5050
V(CODE_MOVE, CodeMoveEventRecord) \
51-
V(CODE_DELETE, CodeDeleteEventRecord) \
5251
V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)
5352

5453

@@ -87,14 +86,6 @@ class CodeMoveEventRecord : public CodeEventRecord {
8786
};
8887

8988

90-
class CodeDeleteEventRecord : public CodeEventRecord {
91-
public:
92-
Address start;
93-
94-
INLINE(void UpdateCodeMap(CodeMap* code_map));
95-
};
96-
97-
9889
class SharedFunctionInfoMoveEventRecord : public CodeEventRecord {
9990
public:
10091
Address from;

src/log.cc

+46-42
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,51 @@ void Logger::LogCodeObjects() {
15271527
}
15281528

15291529

1530+
void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
1531+
Handle<Code> code) {
1532+
Handle<String> func_name(shared->DebugName());
1533+
if (shared->script()->IsScript()) {
1534+
Handle<Script> script(Script::cast(shared->script()));
1535+
if (script->name()->IsString()) {
1536+
Handle<String> script_name(String::cast(script->name()));
1537+
int line_num = GetScriptLineNumber(script, shared->start_position());
1538+
if (line_num > 0) {
1539+
PROFILE(ISOLATE,
1540+
CodeCreateEvent(
1541+
Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1542+
*code, *shared,
1543+
*script_name, line_num + 1));
1544+
} else {
1545+
// Can't distinguish eval and script here, so always use Script.
1546+
PROFILE(ISOLATE,
1547+
CodeCreateEvent(
1548+
Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
1549+
*code, *shared, *script_name));
1550+
}
1551+
} else {
1552+
PROFILE(ISOLATE,
1553+
CodeCreateEvent(
1554+
Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1555+
*code, *shared, *func_name));
1556+
}
1557+
} else if (shared->IsApiFunction()) {
1558+
// API function.
1559+
FunctionTemplateInfo* fun_data = shared->get_api_func_data();
1560+
Object* raw_call_data = fun_data->call_code();
1561+
if (!raw_call_data->IsUndefined()) {
1562+
CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
1563+
Object* callback_obj = call_data->callback();
1564+
Address entry_point = v8::ToCData<Address>(callback_obj);
1565+
PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point));
1566+
}
1567+
} else {
1568+
PROFILE(ISOLATE,
1569+
CodeCreateEvent(
1570+
Logger::LAZY_COMPILE_TAG, *code, *shared, *func_name));
1571+
}
1572+
}
1573+
1574+
15301575
void Logger::LogCompiledFunctions() {
15311576
HandleScope scope;
15321577
const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL);
@@ -1540,48 +1585,7 @@ void Logger::LogCompiledFunctions() {
15401585
if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
15411586
Builtins::kLazyCompile))
15421587
continue;
1543-
Handle<SharedFunctionInfo> shared = sfis[i];
1544-
Handle<String> func_name(shared->DebugName());
1545-
if (shared->script()->IsScript()) {
1546-
Handle<Script> script(Script::cast(shared->script()));
1547-
if (script->name()->IsString()) {
1548-
Handle<String> script_name(String::cast(script->name()));
1549-
int line_num = GetScriptLineNumber(script, shared->start_position());
1550-
if (line_num > 0) {
1551-
PROFILE(ISOLATE,
1552-
CodeCreateEvent(
1553-
Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1554-
*code_objects[i], *shared,
1555-
*script_name, line_num + 1));
1556-
} else {
1557-
// Can't distinguish eval and script here, so always use Script.
1558-
PROFILE(ISOLATE,
1559-
CodeCreateEvent(
1560-
Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
1561-
*code_objects[i], *shared, *script_name));
1562-
}
1563-
} else {
1564-
PROFILE(ISOLATE,
1565-
CodeCreateEvent(
1566-
Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1567-
*code_objects[i], *shared, *func_name));
1568-
}
1569-
} else if (shared->IsApiFunction()) {
1570-
// API function.
1571-
FunctionTemplateInfo* fun_data = shared->get_api_func_data();
1572-
Object* raw_call_data = fun_data->call_code();
1573-
if (!raw_call_data->IsUndefined()) {
1574-
CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
1575-
Object* callback_obj = call_data->callback();
1576-
Address entry_point = v8::ToCData<Address>(callback_obj);
1577-
PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point));
1578-
}
1579-
} else {
1580-
PROFILE(ISOLATE,
1581-
CodeCreateEvent(
1582-
Logger::LAZY_COMPILE_TAG, *code_objects[i],
1583-
*shared, *func_name));
1584-
}
1588+
LogExistingFunction(sfis[i], code_objects[i]);
15851589
}
15861590
}
15871591

src/log.h

+2
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ class Logger {
281281
void ResumeProfiler();
282282
bool IsProfilerPaused();
283283

284+
void LogExistingFunction(Handle<SharedFunctionInfo> shared,
285+
Handle<Code> code);
284286
// Logs all compiled functions found in the heap.
285287
void LogCompiledFunctions();
286288
// Logs all accessor callbacks found in the heap.

src/profile-generator-inl.h

-16
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,6 @@ ProfileNode::ProfileNode(ProfileTree* tree, CodeEntry* entry)
7878
}
7979

8080

81-
void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) {
82-
CodeTree::Locator locator;
83-
tree_.Insert(addr, &locator);
84-
locator.set_value(CodeEntryInfo(entry, size));
85-
}
86-
87-
88-
void CodeMap::MoveCode(Address from, Address to) {
89-
tree_.Move(from, to);
90-
}
91-
92-
void CodeMap::DeleteCode(Address addr) {
93-
tree_.Remove(addr);
94-
}
95-
96-
9781
CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
9882
switch (tag) {
9983
case GC:

src/profile-generator.cc

+32
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,28 @@ const CodeMap::CodeTreeConfig::Value CodeMap::CodeTreeConfig::kNoValue =
492492
CodeMap::CodeEntryInfo(NULL, 0);
493493

494494

495+
void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) {
496+
DeleteAllCoveredCode(addr, addr + size);
497+
CodeTree::Locator locator;
498+
tree_.Insert(addr, &locator);
499+
locator.set_value(CodeEntryInfo(entry, size));
500+
}
501+
502+
503+
void CodeMap::DeleteAllCoveredCode(Address start, Address end) {
504+
List<Address> to_delete;
505+
Address addr = end - 1;
506+
while (addr >= start) {
507+
CodeTree::Locator locator;
508+
if (!tree_.FindGreatestLessThan(addr, &locator)) break;
509+
Address start2 = locator.key(), end2 = start2 + locator.value().size;
510+
if (start2 < end && start < end2) to_delete.Add(start2);
511+
addr = start2 - 1;
512+
}
513+
for (int i = 0; i < to_delete.length(); ++i) tree_.Remove(to_delete[i]);
514+
}
515+
516+
495517
CodeEntry* CodeMap::FindEntry(Address addr) {
496518
CodeTree::Locator locator;
497519
if (tree_.FindGreatestLessThan(addr, &locator)) {
@@ -520,6 +542,16 @@ int CodeMap::GetSharedId(Address addr) {
520542
}
521543

522544

545+
void CodeMap::MoveCode(Address from, Address to) {
546+
if (from == to) return;
547+
CodeTree::Locator locator;
548+
if (!tree_.Find(from, &locator)) return;
549+
CodeEntryInfo entry = locator.value();
550+
tree_.Remove(from);
551+
AddCode(to, entry.entry, entry.size);
552+
}
553+
554+
523555
void CodeMap::CodeTreePrinter::Call(
524556
const Address& key, const CodeMap::CodeEntryInfo& value) {
525557
OS::Print("%p %5d %s\n", key, value.size, value.entry->name());

src/profile-generator.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,8 @@ class CpuProfile {
238238
class CodeMap {
239239
public:
240240
CodeMap() : next_shared_id_(1) { }
241-
INLINE(void AddCode(Address addr, CodeEntry* entry, unsigned size));
242-
INLINE(void MoveCode(Address from, Address to));
243-
INLINE(void DeleteCode(Address addr));
241+
void AddCode(Address addr, CodeEntry* entry, unsigned size);
242+
void MoveCode(Address from, Address to);
244243
CodeEntry* FindEntry(Address addr);
245244
int GetSharedId(Address addr);
246245

@@ -270,6 +269,8 @@ class CodeMap {
270269
void Call(const Address& key, const CodeEntryInfo& value);
271270
};
272271

272+
void DeleteAllCoveredCode(Address start, Address end);
273+
273274
// Fake CodeEntry pointer to distinguish shared function entries.
274275
static CodeEntry* const kSharedFunctionCodeEntry;
275276

src/runtime.cc

+5
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
22432243
// are guaranteed to be in old space.
22442244
target->set_literals(*literals, SKIP_WRITE_BARRIER);
22452245
target->set_next_function_link(isolate->heap()->undefined_value());
2246+
2247+
if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) {
2248+
isolate->logger()->LogExistingFunction(
2249+
shared, Handle<Code>(shared->code()));
2250+
}
22462251
}
22472252

22482253
target->set_context(*context);

test/cctest/log-eq-of-logging-and-traversal.js

+5-13
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ function LogProcessor() {
4343
processor: this.processCodeCreation },
4444
'code-move': { parsers: [parseInt, parseInt],
4545
processor: this.processCodeMove },
46-
'code-delete': { parsers: [parseInt],
47-
processor: this.processCodeDelete },
46+
'code-delete': null,
4847
'sfi-move': { parsers: [parseInt, parseInt],
4948
processor: this.processFunctionMove },
5049
'shared-library': null,
@@ -73,10 +72,6 @@ LogProcessor.prototype.processCodeMove = function(from, to) {
7372
this.profile.moveCode(from, to);
7473
};
7574

76-
LogProcessor.prototype.processCodeDelete = function(start) {
77-
this.profile.deleteCode(start);
78-
};
79-
8075
LogProcessor.prototype.processFunctionMove = function(from, to) {
8176
this.profile.moveFunc(from, to);
8277
};
@@ -132,8 +127,8 @@ function RunTest() {
132127
"Script", "String", "RegExp", "Date", "Error"];
133128

134129
function entitiesEqual(entityA, entityB) {
135-
if (entityA === null && entityB !== null) return true;
136-
if (entityA !== null && entityB === null) return false;
130+
if ((entityA === null && entityB !== null) ||
131+
(entityA !== null && entityB === null)) return true;
137132
return entityA.size === entityB.size && entityNamesEqual(entityA, entityB);
138133
}
139134

@@ -145,6 +140,8 @@ function RunTest() {
145140
// find the same entries. We skip builtins during log parsing, but compiled
146141
// functions traversal may erroneously recognize them as functions, so we are
147142
// expecting more functions in traversal vs. logging.
143+
// Since we don't track code deletions, logging can also report more entries
144+
// than traversal.
148145
while (l_pos < l_len && t_pos < t_len) {
149146
var entryA = logging_entries[l_pos];
150147
var entryB = traversal_entries[t_pos];
@@ -166,11 +163,6 @@ function RunTest() {
166163
if (!entities_equal) equal = false;
167164
comparison.push([entities_equal, address, entityA, entityB]);
168165
}
169-
if (l_pos < l_len) equal = false;
170-
while (l_pos < l_len) {
171-
var entryA = logging_entries[l_pos++];
172-
comparison.push([false, entryA[0], entryA[1], null]);
173-
}
174166
return [equal, comparison];
175167
}
176168

test/cctest/test-cpu-profiler.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ TEST(CodeEvents) {
107107
0x80);
108108
processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500));
109109
processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10);
110-
processor.CodeDeleteEvent(ToAddress(0x1600));
110+
processor.CodeCreateEvent(i::Logger::STUB_TAG, 4, ToAddress(0x1605), 0x10);
111111
// Enqueue a tick event to enable code events processing.
112112
EnqueueTickSampleEvent(&processor, ToAddress(0x1000));
113113

test/cctest/test-log.cc

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ using v8::internal::StrLength;
2525

2626
namespace {
2727

28+
2829
class ScopedLoggerInitializer {
2930
public:
3031
explicit ScopedLoggerInitializer(bool prof_lazy)
@@ -470,8 +471,9 @@ TEST(IsLoggingPreserved) {
470471

471472
typedef i::NativesCollection<i::TEST> TestSources;
472473

473-
// Test that logging of code create / move / delete events
474-
// is equivalent to traversal of a resulting heap.
474+
475+
// Test that logging of code create / move events is equivalent to traversal of
476+
// a resulting heap.
475477
TEST(EquivalenceOfLoggingAndTraversal) {
476478
// This test needs to be run on a "clean" V8 to ensure that snapshot log
477479
// is loaded. This is always true when running using tools/test.py because

test/cctest/test-profile-generator.cc

+6-5
Original file line numberDiff line numberDiff line change
@@ -549,13 +549,14 @@ TEST(CodeMapMoveAndDeleteCode) {
549549
code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
550550
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
551551
CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
552-
code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1800));
552+
code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700)); // Deprecate bbb.
553553
CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500)));
554-
CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
555-
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800)));
556-
code_map.DeleteCode(ToAddress(0x1700));
554+
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700)));
555+
CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
556+
TokenEnumerator::kNoSecurityToken);
557+
code_map.AddCode(ToAddress(0x1750), &entry3, 0x100);
557558
CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700)));
558-
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800)));
559+
CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750)));
559560
}
560561

561562

0 commit comments

Comments
 (0)