v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
d8-console.cc
Go to the documentation of this file.
1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/d8/d8-console.h"
6
7#include <stdio.h>
8
9#include <fstream>
10
11#include "include/v8-profiler.h"
12#include "src/d8/d8.h"
14
15namespace v8 {
16
17namespace {
18void WriteToFile(const char* prefix, FILE* file, Isolate* isolate,
19 const debug::ConsoleCallArguments& args) {
20 if (prefix) fprintf(file, "%s: ", prefix);
21 for (int i = 0; i < args.Length(); i++) {
22 HandleScope handle_scope(isolate);
23 if (i > 0) fprintf(file, " ");
24
25 Local<Value> arg = args[i];
26 Local<String> str_obj;
27
28 if (arg->IsSymbol()) arg = Local<Symbol>::Cast(arg)->Description(isolate);
29 if (!arg->ToString(isolate->GetCurrentContext()).ToLocal(&str_obj)) return;
30
31 v8::String::Utf8Value str(isolate, str_obj);
32 size_t n = fwrite(*str, sizeof(**str), str.length(), file);
33 if (n != str.length()) {
34 printf("Error in fwrite\n");
36 }
37 }
38 fprintf(file, "\n");
39 // Flush the file to avoid output to pile up in a buffer. Console output is
40 // often used for timing, so it should appear as soon as the code is executed.
41 fflush(file);
42}
43
44class FileOutputStream : public v8::OutputStream {
45 public:
46 explicit FileOutputStream(const char* filename)
47 : os_(filename, std::ios_base::out | std::ios_base::trunc) {}
48
49 WriteResult WriteAsciiChunk(char* data, int size) override {
50 os_.write(data, size);
51 return kContinue;
52 }
53
54 void EndOfStream() override { os_.close(); }
55
56 private:
57 std::ofstream os_;
58};
59
60static constexpr const char* kCpuProfileOutputFilename = "v8.prof";
61
62class StringOutputStream : public v8::OutputStream {
63 public:
64 WriteResult WriteAsciiChunk(char* data, int size) override {
65 os_.write(data, size);
66 return kContinue;
67 }
68
69 void EndOfStream() override {}
70
71 std::string result() { return os_.str(); }
72
73 private:
74 std::ostringstream os_;
75};
76
77std::optional<std::string> GetTimerLabel(
78 const debug::ConsoleCallArguments& args) {
79 if (args.Length() == 0) return "default";
80 Isolate* isolate = args.GetIsolate();
81 v8::TryCatch try_catch(isolate);
82 v8::String::Utf8Value label(isolate, args[0]);
83 if (*label == nullptr) return std::nullopt;
84 return std::string(*label, label.length());
85}
86
87} // anonymous namespace
88
90 : isolate_(isolate), origin_(base::TimeTicks::Now()) {}
91
93
95 if (profiler_) {
96 if (profiler_active_) {
98 profiler_active_ = false;
99 }
101 profiler_ = nullptr;
102 }
103}
104
107 // If no arguments given, the "first" argument is undefined which is
108 // false-ish.
109 if (args.Length() > 0 && args[0]->BooleanValue(isolate_)) return;
110 WriteToFile("console.assert", stdout, isolate_, args);
111 isolate_->ThrowError("console.assert failed");
112}
113
118
121 WriteToFile("console.error", stderr, isolate_, args);
122}
123
126 WriteToFile("console.warn", stdout, isolate_, args);
127}
128
131 WriteToFile("console.info", stdout, isolate_, args);
132}
133
136 WriteToFile("console.debug", stdout, isolate_, args);
137}
138
147
150 if (!profiler_) return;
152 profiler_active_ = false;
153 if (!profile) return;
155 StringOutputStream out;
156 profile->Serialize(&out);
158 } else {
159 FileOutputStream out(kCpuProfileOutputFilename);
160 profile->Serialize(&out);
161 }
162 profile->Delete();
163}
164
167 if (i::v8_flags.correctness_fuzzer_suppressions) return;
168 std::optional label = GetTimerLabel(args);
169 if (!label.has_value()) return;
170 if (!timers_.try_emplace(label.value(), base::TimeTicks::Now()).second) {
171 printf("console.time: Timer '%s' already exists\n", label.value().c_str());
172 }
173}
174
177 if (i::v8_flags.correctness_fuzzer_suppressions) return;
178 std::optional label = GetTimerLabel(args);
179 if (!label.has_value()) return;
180 auto it = timers_.find(label.value());
181 if (it == timers_.end()) {
182 printf("console.timeLog: Timer '%s' does not exist\n",
183 label.value().c_str());
184 return;
185 }
186 base::TimeDelta delta = base::TimeTicks::Now() - it->second;
187 printf("console.timeLog: %s, %f\n", label.value().c_str(),
188 delta.InMillisecondsF());
189}
190
193 if (i::v8_flags.correctness_fuzzer_suppressions) return;
194 std::optional label = GetTimerLabel(args);
195 if (!label.has_value()) return;
196 auto it = timers_.find(label.value());
197 if (it == timers_.end()) {
198 printf("console.timeEnd: Timer '%s' does not exist\n",
199 label.value().c_str());
200 return;
201 }
202 base::TimeDelta delta = base::TimeTicks::Now() - it->second;
203 printf("console.timeEnd: %s, %f\n", label.value().c_str(),
204 delta.InMillisecondsF());
205 timers_.erase(it);
206}
207
210 if (i::v8_flags.correctness_fuzzer_suppressions) return;
211 std::optional label = GetTimerLabel(args);
212 if (!label.has_value()) return;
214 printf("console.timeStamp: %s, %f\n", label.value().c_str(),
215 delta.InMillisecondsF());
216}
217
220 if (i::v8_flags.correctness_fuzzer_suppressions) return;
221 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
222 i_isolate->PrintStack(stderr, i::Isolate::kPrintStackConcise);
223}
224
225} // namespace v8
Isolate * isolate_
void Delete()
Definition api.cc:11320
CpuProfilingStatus StartProfiling(Local< String > title, CpuProfilingOptions options, std::unique_ptr< DiscardedSamplesDelegate > delegate=nullptr)
Definition api.cc:11475
static CpuProfiler * New(Isolate *isolate, CpuProfilingNamingMode=kDebugNaming, CpuProfilingLoggingMode=kLazyLogging)
Definition api.cc:11391
CpuProfile * StopProfiling(Local< String > title)
Definition api.cc:11493
void Dispose()
Definition api.cc:11420
CpuProfiler * profiler_
Definition d8-console.h:62
D8Console(Isolate *isolate)
Definition d8-console.cc:89
void Error(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
void Debug(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
bool profiler_active_
Definition d8-console.h:63
void ProfileEnd(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &context) override
base::TimeTicks origin_
Definition d8-console.h:61
void Trace(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
void TimeLog(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
void Info(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
void Profile(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &context) override
void TimeEnd(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
std::map< std::string, base::TimeTicks > timers_
Definition d8-console.h:59
void Log(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
~D8Console() override
Definition d8-console.cc:92
void DisposeProfiler()
Definition d8-console.cc:94
Isolate * isolate_
Definition d8-console.h:54
void Assert(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
void Warn(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
void TimeStamp(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
void Time(const debug::ConsoleCallArguments &args, const v8::debug::ConsoleContext &) override
Local< Value > ThrowError(const char(&message)[N])
static V8_INLINE Local< T > Cast(Local< S > that)
static void TriggerOnProfileEndListener(Isolate *isolate, std::string profile)
Definition d8.cc:2862
static bool HasOnProfileEndListener(Isolate *isolate)
Definition d8.cc:2829
static V8_INLINE Local< String > Empty(Isolate *isolate)
static void ExitProcess(int exit_code)
double InMillisecondsF() const
Definition time.cc:226
static TimeTicks Now()
Definition time.cc:736
void PrintStack(StringStream *accumulator, PrintStackMode mode=kPrintStackVerbose)
Definition isolate.cc:1757
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
Label label
std::string filename
ZoneVector< RpoNumber > & result
STL namespace.
V8_EXPORT_PRIVATE FlagValues v8_flags
void WriteToFile(FILE *file, const v8::FunctionCallbackInfo< v8::Value > &info, int first_arg_index=0)
Definition d8.cc:2879
#define DCHECK_NULL(val)
Definition logging.h:491
std::ostream * os_