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

Side by Side Diff: test/cctest/bytecodechecker.cc

Issue 1671863002: [Interpreter] Initial generate-bytecode-expectations implementation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/cctest/cctest.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 <iostream>
6 #include "include/libplatform/libplatform.h"
7 #include "src/base/logging.h"
8 #include "src/compiler.h"
9 #include "src/interpreter/bytecode-array-iterator.h"
10 #include "src/interpreter/bytecode-generator.h"
11 #include "src/interpreter/bytecodes.h"
12 #include "src/interpreter/interpreter.h"
13 #include "src/v8.h"
oth 2016/02/05 11:41:04 Is there something specific from src/v8.h? Samples
Stefano Sanfilippo 2016/02/08 13:18:34 No there's nothing specific ATM, I was just follow
14
15 using namespace i::interpreter;
16
17 namespace {
18
19 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator {
20 public:
21 void *Allocate(size_t length) override {
oth 2016/02/05 11:41:05 The predominant style in v8 is "void*" rather than
Stefano Sanfilippo 2016/02/08 13:18:34 Done.
rmcilroy 2016/02/08 13:55:31 Doesn't look like this has been done.
Stefano Sanfilippo 2016/02/09 10:09:58 It was, but cl format reverted to this style befor
rmcilroy 2016/02/09 11:58:24 Hmm that's weird (git cl format doesn't do that fo
Stefano Sanfilippo 2016/02/09 16:52:50 I finally did it on the workstation. Maybe it's a
rmcilroy 2016/02/10 09:18:00 Sounds like it - weird. thanks!
22 void *data = AllocateUninitialized(length);
23 if (data != nullptr) memset(data, 0, length);
24 return data;
25 }
26 void *AllocateUninitialized(size_t length) override { return malloc(length); }
27 void Free(void *data, size_t) override { free(data); }
28 };
29
30 class PlatformWrapper final {
31 public:
32 PlatformWrapper(const char *program_name, const char *wrapper_function_name);
33 ~PlatformWrapper();
34
35 PlatformWrapper(PlatformWrapper &) = delete;
oth 2016/02/05 11:41:04 V8 code generally packages this up with (doesn't d
Stefano Sanfilippo 2016/02/08 13:18:34 Done.
36 PlatformWrapper(PlatformWrapper &&) = delete;
37
38 v8::Platform *platform() const { return platform_; }
39 v8::Isolate *isolate() const { return isolate_; }
40 i::Isolate *i_isolate() const {
41 return reinterpret_cast<i::Isolate *>(isolate_);
42 }
43
44 private:
45 v8::Platform *platform_;
46 v8::Isolate *isolate_;
rmcilroy 2016/02/05 13:49:51 use base::SmartPointer<...> for both of these obje
Stefano Sanfilippo 2016/02/08 13:18:34 Done for platform_. base::SmartPointer doesn't see
47 };
48
49 enum ConstantPoolType {
50 kConstantPoolTypeUnknown = 0,
51 kConstantPoolTypeString,
52 kConstantPoolTypeInteger,
53 kConstantPoolTypeFloat,
54 };
rmcilroy 2016/02/05 13:49:51 Not used yet - remove for now.
Stefano Sanfilippo 2016/02/08 13:18:34 Done.
55
56 PlatformWrapper::PlatformWrapper(const char *program_name,
rmcilroy 2016/02/05 13:49:51 /s/program_name/exec_path
Stefano Sanfilippo 2016/02/08 13:18:34 Done.
57 const char *wrapper_function_name) {
rmcilroy 2016/02/05 13:49:51 no need to pass this to the PlatformWrapper, just
Stefano Sanfilippo 2016/02/08 13:18:34 Ok, for the moment I replaced the filter with a "*
58 v8::V8::InitializeICU();
59 v8::V8::InitializeExternalStartupData(program_name);
60 platform_ = v8::platform::CreateDefaultPlatform();
61 v8::V8::InitializePlatform(platform_);
62 v8::V8::Initialize();
63
64 ArrayBufferAllocator allocator;
65 v8::Isolate::CreateParams create_params;
66 create_params.array_buffer_allocator = &allocator;
67
68 isolate_ = v8::Isolate::New(create_params);
69 i::FLAG_ignition = true;
70 i::FLAG_ignition_filter = i::StrDup(wrapper_function_name);
71 i::FLAG_always_opt = false;
72 i::FLAG_allow_natives_syntax = true;
73 i::FLAG_legacy_const = true;
rmcilroy 2016/02/05 13:49:51 just move these to the top of the function, then t
Stefano Sanfilippo 2016/02/08 13:18:34 Done.
74 i_isolate()->interpreter()->Initialize();
75 }
76
77 PlatformWrapper::~PlatformWrapper() {
78 isolate_->Dispose();
79 v8::V8::Dispose();
80 v8::V8::ShutdownPlatform();
81 delete platform_;
82 platform_ = nullptr;
83 }
84
85 v8::Local<v8::String> MakeV8LocalStringFromUTF8(const PlatformWrapper &platform,
86 const char *data) {
87 return v8::String::NewFromUtf8(platform.isolate(), data,
88 v8::NewStringType::kNormal)
89 .ToLocalChecked();
90 }
91
92 static std::string WrapCodeInFunction(const char *function_name,
93 const std::string &body) {
94 std::ostringstream program_stream;
95 program_stream << "function " << function_name << "() {" << body << "}\n"
96 << function_name << "();";
97
98 return program_stream.str();
99 }
100
101 v8::Local<v8::Value> CompileAndRun(const PlatformWrapper &platform,
102 const v8::Local<v8::Context> &context,
103 const char *program) {
104 v8::Local<v8::String> source = MakeV8LocalStringFromUTF8(platform, program);
105 v8::Local<v8::Script> script =
106 v8::Script::Compile(context, source).ToLocalChecked();
107
108 v8::Local<v8::Value> result;
109 bool success = script->Run(context).ToLocal(&result);
110 CHECK(success);
111
112 return result;
113 }
114
115 i::Handle<v8::internal::BytecodeArray> GetBytecodeArrayForGlobal(
116 const PlatformWrapper &platform, const v8::Local<v8::Context> &context,
117 const char *global_name) {
118 v8::Local<v8::String> v8_global_name =
119 MakeV8LocalStringFromUTF8(platform, global_name);
120 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
121 context->Global()->Get(context, v8_global_name).ToLocalChecked());
122 i::Handle<i::JSFunction> js_function =
123 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function));
124
125 i::Handle<i::BytecodeArray> bytecodes =
126 i::handle(js_function->shared()->bytecode_array(), platform.i_isolate());
127
128 return bytecodes;
129 }
130
131 void PrintBytecodeOperand(std::ostream &stream,
132 const BytecodeArrayIterator &bytecode_iter,
133 const Bytecode &bytecode, int op_index) {
134 OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index);
135
136 switch (op_type) {
137 case OperandType::kMaybeReg8:
138 case OperandType::kReg8:
139 case OperandType::kRegPair8:
140 case OperandType::kRegOut8:
141 case OperandType::kRegOutTriple8:
142 case OperandType::kRegOutPair8: {
143 Register op_value_register = bytecode_iter.GetRegisterOperand(op_index);
144 stream << "R(" << op_value_register.index() << ')';
145 break;
146 }
147 case OperandType::kMaybeReg16:
148 case OperandType::kReg16:
149 case OperandType::kRegPair16:
150 case OperandType::kRegOut16:
151 case OperandType::kRegOutTriple16:
152 case OperandType::kRegOutPair16: {
153 Register op_value_register = bytecode_iter.GetRegisterOperand(op_index);
154 stream << "R16(" << op_value_register.index() << ')';
155 break;
156 }
157 case OperandType::kImm8: {
158 int op_value_immediate = bytecode_iter.GetImmediateOperand(op_index);
159 stream << "U8(" << op_value_immediate << ')';
160 break;
161 }
162 case OperandType::kIdx8: {
163 int op_value_index = bytecode_iter.GetIndexOperand(op_index);
164 stream << "U8(" << op_value_index << ')';
165 break;
166 }
167 case OperandType::kRegCount8: {
168 int op_value_regcount = bytecode_iter.GetCountOperand(op_index);
169 stream << "U8(" << op_value_regcount << ')';
170 break;
171 }
172 case OperandType::kIdx16: {
173 int op_value_index = bytecode_iter.GetIndexOperand(op_index);
174 stream << "U16(" << op_value_index << ')';
175 break;
176 }
177 case OperandType::kRegCount16: {
178 int op_value_regcount = bytecode_iter.GetCountOperand(op_index);
179 stream << "U8(" << op_value_regcount << ')';
rmcilroy 2016/02/05 13:49:51 This should be U16
Stefano Sanfilippo 2016/02/08 13:18:34 Silly copy and paste mistake is silly. Fixed.
180 break;
181 }
rmcilroy 2016/02/05 13:49:51 Personally I would prefer that this is written usi
Stefano Sanfilippo 2016/02/08 13:18:34 Seems OK to me, as long as GetRawOperand() is guar
rmcilroy 2016/02/08 13:55:31 Yup, I think this should always be safe.
182 default:
183 UNREACHABLE();
184 return;
185 }
186 }
187
188 void PrintBytecode(std::ostream &stream,
189 const BytecodeArrayIterator &bytecode_iter) {
190 Bytecode bytecode = bytecode_iter.current_bytecode();
191
192 stream << "B(" << Bytecodes::ToString(bytecode) << ')';
rmcilroy 2016/02/05 13:49:51 You will need a comma after the B(..) or the final
193
194 int operands_count = Bytecodes::NumberOfOperands(bytecode);
195 for (int op_index = 0; op_index < operands_count; ++op_index) {
196 stream << ", ";
197 PrintBytecodeOperand(stream, bytecode_iter, bytecode, op_index);
198 }
199 }
200
201 void PrintBytecodeArray(std::ostream &stream,
oth 2016/02/05 11:41:04 Something for you and Ross, but consider emitting
rmcilroy 2016/02/05 13:49:51 +1
Stefano Sanfilippo 2016/02/08 13:18:34 Done, I have added a boolean flag to print a banne
202 i::Handle<i::BytecodeArray> bytecode_array) {
203 const int kPointerSize = sizeof(void *);
204
205 int frame_size = bytecode_array->frame_size();
206 if (frame_size > kPointerSize) {
207 stream << ' ' << frame_size / kPointerSize << " * kPointerSize,\n";
rmcilroy 2016/02/05 13:49:51 Could you make these indented by the same amount a
Stefano Sanfilippo 2016/02/08 13:18:34 Done. For now the indent amount is hardcoded becau
208 } else if (frame_size == kPointerSize) {
209 stream << " kPointerSize,\n";
210 } else {
211 stream << " 0,\n";
212 }
213
214 stream << ' ' << bytecode_array->parameter_count() << ",\n"
215 << ' ' << bytecode_array->length() << ",\n {\n ";
216
217 BytecodeArrayIterator bytecode_iter{bytecode_array};
218
219 bool emitting_first_instruction = true;
220 for (; !bytecode_iter.done(); bytecode_iter.Advance()) {
221 // Print separator before each instruction, except the first one
222 if (!emitting_first_instruction) {
oth 2016/02/05 11:41:04 The code can be simplified here using BytecodeIter
rmcilroy 2016/02/05 13:49:51 Also, again trailing commas are OK I think, so you
Stefano Sanfilippo 2016/02/08 13:18:34 I ended up following oth suggestion, which simplif
rmcilroy 2016/02/08 13:55:31 SGTM, thanks.
223 stream << ",\n ";
224 } else {
225 emitting_first_instruction = false;
226 }
227
228 PrintBytecode(stream, bytecode_iter);
229 }
230
231 stream << "\n },\n";
232 }
233
234 } // namespace
235
236 int main(int argc, char **argv) {
237 if (argc < 2) {
238 std::cerr << "Usage: " << argv[0] << " \"return null;\"\n";
oth 2016/02/05 11:41:05 This usage message is cryptic. Going forward, it
rmcilroy 2016/02/05 13:49:51 +1, I would have it read from stdin in this CL sin
Stefano Sanfilippo 2016/02/08 13:18:34 Done. 0 arguments or "-" means stdin, anything els
239 return 1;
240 }
241
242 const char *body = argv[1];
243 const char *wrapper_function_name = "__bytecodechecker_wrapper__";
244
245 PlatformWrapper platform(argv[0], wrapper_function_name);
rmcilroy 2016/02/05 13:49:51 I'd rename PlatformWrapper as V8InitializationScop
Stefano Sanfilippo 2016/02/08 13:18:34 Done.
246 {
247 v8::Isolate::Scope isolate_scope(platform.isolate());
248 v8::HandleScope handle_scope(platform.isolate());
249 v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
250 v8::Context::Scope context_scope(context);
251
252 std::string source_code = WrapCodeInFunction(wrapper_function_name, body);
253 CompileAndRun(platform, context, source_code.c_str());
254
255 i::Handle<i::BytecodeArray> bytecode_array =
256 GetBytecodeArrayForGlobal(platform, context, wrapper_function_name);
257
258 std::cout << "{" << '"' << body << "\",\n";
rmcilroy 2016/02/05 13:49:51 nit - move this into PrintBytecodeArray (and the c
Stefano Sanfilippo 2016/02/08 13:18:34 Done.
259
260 PrintBytecodeArray(std::cout, bytecode_array);
261
262 std::cout << "}\n";
263 }
264 }
OLDNEW
« no previous file with comments | « no previous file | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698