[log] Support logging two-byte characters

Bug: chromium:1130673
Change-Id: I78ae388daa1c4c2b594981bdadd201c2dfb39eb0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2426618
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70116}
This commit is contained in:
Camillo Bruni 2020-09-24 09:39:15 +02:00 committed by Commit Bot
parent d382dab9e5
commit 78c42a1f8e
7 changed files with 69 additions and 11 deletions

View File

@ -128,12 +128,19 @@ void Log::MessageBuilder::AppendString(const char* str) {
AppendString(str, strlen(str));
}
void Log::MessageBuilder::AppendString(const char* str, size_t length) {
void Log::MessageBuilder::AppendString(const char* str, size_t length,
bool is_one_byte) {
if (str == nullptr) return;
for (size_t i = 0; i < length; i++) {
DCHECK_NE(str[i], '\0');
AppendCharacter(str[i]);
if (is_one_byte) {
for (size_t i = 0; i < length; i++) {
DCHECK_IMPLIES(is_one_byte, str[i] != '\0');
AppendCharacter(str[i]);
}
} else {
DCHECK_EQ(length % 2, 0);
for (size_t i = 0; i + 1 < length; i += 2) {
AppendTwoByteCharacter(str[i], str[i + 1]);
}
}
}
@ -148,6 +155,14 @@ void Log::MessageBuilder::AppendFormatString(const char* format, ...) {
}
}
void Log::MessageBuilder::AppendTwoByteCharacter(char c1, char c2) {
if (c2 == 0) {
AppendCharacter(c1);
} else {
// Escape non-printable characters.
AppendRawFormatString("\\u%02x%02x", c1 & 0xFF, c2 & 0xFF);
}
}
void Log::MessageBuilder::AppendCharacter(char c) {
if (c >= 32 && c <= 126) {
if (c == ',') {

View File

@ -69,9 +69,10 @@ class Log {
base::Optional<int> length_limit = base::nullopt);
void AppendString(Vector<const char> str);
void AppendString(const char* str);
void AppendString(const char* str, size_t length);
void AppendString(const char* str, size_t length, bool is_one_byte = true);
void PRINTF_FORMAT(2, 3) AppendFormatString(const char* format, ...);
void AppendCharacter(char c);
void AppendTwoByteCharacter(char c1, char c2);
void AppendSymbolName(Symbol symbol);
// Delegate insertion to the underlying {log_}.

View File

@ -1602,7 +1602,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
int start_position, int end_position,
const char* function_name,
size_t function_name_length) {
size_t function_name_length, bool is_one_byte) {
if (!FLAG_log_function_events) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
if (!msg_ptr) return;
@ -1610,7 +1610,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
end_position, &timer_);
if (function_name_length > 0) {
msg.AppendString(function_name, function_name_length);
msg.AppendString(function_name, function_name_length, is_one_byte);
}
msg.WriteToLogFile();
}

View File

@ -170,7 +170,7 @@ class Logger : public CodeEventListener {
void FunctionEvent(const char* reason, int script_id, double time_delta_ms,
int start_position, int end_position,
const char* function_name = nullptr,
size_t function_name_length = 0);
size_t function_name_length = 0, bool is_one_byte = true);
void CompilationCacheEvent(const char* action, const char* cache_type,
SharedFunctionInfo sfi);

View File

@ -2507,7 +2507,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
event_name, flags().script_id(), ms, scope->start_position(),
scope->end_position(),
reinterpret_cast<const char*>(function_name->raw_data()),
function_name->byte_length());
function_name->byte_length(), function_name->is_one_byte());
}
if (V8_UNLIKELY(TracingFlags::is_runtime_stats_enabled()) &&
did_preparse_successfully) {

View File

@ -347,14 +347,16 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// reconstructed from the script id and the byte range in the log processor.
const char* name = "";
size_t name_byte_length = 0;
bool is_one_byte = true;
const AstRawString* string = function_name.string_;
if (string != nullptr) {
name = reinterpret_cast<const char*>(string->raw_data());
name_byte_length = string->byte_length();
is_one_byte = string->is_one_byte();
}
logger_->FunctionEvent(
event_name, flags().script_id(), ms, function_scope->start_position(),
function_scope->end_position(), name, name_byte_length);
function_scope->end_position(), name, name_byte_length, is_one_byte);
}
return Expression::Default();

View File

@ -0,0 +1,40 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --logfile='+' --log --log-code --log-function-events --no-stress-opt
let twoByteName = "twoByteName_🍕"
let o = {
[twoByteName](obj) {
return obj.a
}
}
function testFunctionWithFunnyName(o) {
return o.a;
}
(function testLoopWithFunnyName() {
let object = {a:1};
let result = 0;
for (let i = 0; i < 1000; i++) {
result += o[twoByteName](object);
}
console.log(result);
console.log(twoByteName);
})();
var __v_3 = {};
({})['foobar\u2653'] = null;
eval('__v_3 = function foobar() { return foobar };');
__v_3();
const log = d8.log.getAndStop();
console.log(log)
// Check that we have a minimally working log file.
assertTrue(log.length > 0);
assertTrue(log.indexOf('v8-version') == 0);
assertTrue(log.indexOf('testFunctionWithFunnyName') >= 10);
assertTrue(log.indexOf("twoByteName") >= 10);
assertTrue(log.indexOf('testLoopWithFunnyName') >= 10);