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

Side by Side Diff: test/cctest/interpreter/bytecode-expectations.cc

Issue 1688383003: [Interpreter] Change the output format of generate-bytecode-expectations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix help message. 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
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 "test/cctest/interpreter/bytecode-expectations.h"
6
7 #include <iostream>
8
9 #include "include/libplatform/libplatform.h"
10 #include "include/v8.h"
11
12 #include "src/base/logging.h"
13 #include "src/base/smart-pointers.h"
14 #include "src/compiler.h"
15
16 #include "src/interpreter/bytecode-array-iterator.h"
17 #include "src/interpreter/bytecode-generator.h"
18 #include "src/interpreter/bytecodes.h"
19 #include "src/interpreter/interpreter.h"
20
21 using namespace v8::internal::interpreter;
22
23 namespace {
24
25 i::Isolate* GetInternalIsolate(v8::Isolate* isolate) {
rmcilroy 2016/02/12 15:29:05 Move this to generate-bytecode-expectations.cc and
Stefano Sanfilippo 2016/02/12 18:29:40 Turns out we need the external Isolate as well, fo
rmcilroy 2016/02/15 11:15:19 What you've done here is fine (modulo the rename o
26 return reinterpret_cast<i::Isolate*>(isolate);
27 }
28
29 v8::Local<v8::String> V8StringFromUTF8(v8::Isolate* isolate, const char* data) {
30 return v8::String::NewFromUtf8(isolate, data, v8::NewStringType::kNormal)
31 .ToLocalChecked();
32 }
33
34 std::string WrapCodeInFunction(const char* function_name,
35 const std::string& function_body) {
36 std::ostringstream program_stream;
37 program_stream << "function " << function_name << "() {" << function_body
38 << "}\n"
39 << function_name << "();";
40
41 return program_stream.str();
42 }
43
44 v8::Local<v8::Value> CompileAndRun(v8::Isolate* isolate, const char* program) {
45 v8::Local<v8::String> source = V8StringFromUTF8(isolate, program);
46 v8::Local<v8::Script> script =
47 v8::Script::Compile(isolate->GetCurrentContext(), source)
48 .ToLocalChecked();
49
50 v8::Local<v8::Value> result;
51 CHECK(script->Run(isolate->GetCurrentContext()).ToLocal(&result));
52
53 return result;
54 }
55
56 i::Handle<v8::internal::BytecodeArray> GetBytecodeArrayForGlobal(
57 v8::Isolate* isolate, const char* global_name) {
58 const v8::Local<v8::Context>& context = isolate->GetCurrentContext();
59 v8::Local<v8::String> v8_global_name = V8StringFromUTF8(isolate, global_name);
60 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
61 context->Global()->Get(context, v8_global_name).ToLocalChecked());
62 i::Handle<i::JSFunction> js_function =
63 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function));
64
65 i::Handle<i::BytecodeArray> bytecodes = i::handle(
66 js_function->shared()->bytecode_array(), GetInternalIsolate(isolate));
67
68 return bytecodes;
69 }
70
71 void PrintEscapedString(std::ostream& stream, const std::string& string) {
72 for (char c : string) {
73 switch (c) {
74 case '"':
75 stream << "\\\"";
76 break;
77 case '\\':
78 stream << "\\\\";
79 break;
80 default:
81 stream << c;
82 break;
83 }
84 }
85 }
86
87 void PrintBytecodeOperand(std::ostream& stream,
rmcilroy 2016/02/12 15:29:05 Functions from here onwards should be private func
Stefano Sanfilippo 2016/02/12 18:29:40 Done.
88 const BytecodeArrayIterator& bytecode_iter,
89 const Bytecode& bytecode, int op_index) {
90 OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index);
91 OperandSize op_size = Bytecodes::GetOperandSize(bytecode, op_index);
92
93 const char* size_tag;
94 switch (op_size) {
95 case OperandSize::kByte:
96 size_tag = "8";
97 break;
98 case OperandSize::kShort:
99 size_tag = "16";
100 break;
101 default:
102 UNREACHABLE();
103 return;
104 }
105
106 if (Bytecodes::IsRegisterOperandType(op_type)) {
107 Register register_value = bytecode_iter.GetRegisterOperand(op_index);
108 stream << 'R';
109 if (op_size != OperandSize::kByte) stream << size_tag;
110 stream << '(' << register_value.index() << ')';
111 } else {
112 stream << 'U' << size_tag << '(';
113
114 if (Bytecodes::IsImmediateOperandType(op_type)) {
115 // We need a cast, otherwise the result is printed as char.
116 stream << static_cast<int>(bytecode_iter.GetImmediateOperand(op_index));
117 } else if (Bytecodes::IsRegisterCountOperandType(op_type)) {
118 stream << bytecode_iter.GetRegisterCountOperand(op_index);
119 } else if (Bytecodes::IsIndexOperandType(op_type)) {
120 stream << bytecode_iter.GetIndexOperand(op_index);
121 } else {
122 UNREACHABLE();
123 }
124
125 stream << ')';
126 }
127 }
128
129 void PrintBytecode(std::ostream& stream,
130 const BytecodeArrayIterator& bytecode_iter) {
131 Bytecode bytecode = bytecode_iter.current_bytecode();
132
133 stream << "B(" << Bytecodes::ToString(bytecode) << ')';
134
135 int operands_count = Bytecodes::NumberOfOperands(bytecode);
136 for (int op_index = 0; op_index < operands_count; ++op_index) {
137 stream << ", ";
138 PrintBytecodeOperand(stream, bytecode_iter, bytecode, op_index);
139 }
140 }
141
142 void PrintV8String(std::ostream& stream, i::String* string) {
143 stream << '"';
144 for (int i = 0, length = string->length(); i < length; ++i) {
145 stream << i::AsEscapedUC16ForJSON(string->Get(i));
146 }
147 stream << '"';
148 }
149
150 void PrintConstant(std::ostream& stream,
151 ConstantPoolType expected_constant_type,
152 i::Handle<i::Object> constant) {
153 switch (expected_constant_type) {
154 case kConstantPoolTypeString:
155 CHECK(constant->IsString());
156 PrintV8String(stream, i::String::cast(*constant));
157 break;
158 case kConstantPoolTypeInteger:
159 if (constant->IsSmi()) {
160 i::Smi::cast(*constant)->SmiPrint(stream);
161 } else if (constant->IsHeapNumber()) {
162 i::HeapNumber::cast(*constant)->HeapNumberPrint(stream);
163 } else {
164 UNREACHABLE();
165 }
166 break;
167 case kConstantPoolTypeDouble:
168 i::HeapNumber::cast(*constant)->HeapNumberPrint(stream);
169 break;
170 case kConstantPoolTypeMixed:
171 if (constant->IsSmi()) {
172 stream << "kInstanceTypeDontCare";
173 } else {
174 stream << "InstanceType::"
175 << i::HeapObject::cast(*constant)->map()->instance_type();
176 }
177 break;
178 case kConstantPoolTypeUnknown:
179 default:
180 UNREACHABLE();
181 return;
182 }
183 }
184
185 void PrintFrameSize(std::ostream& stream,
186 i::Handle<i::BytecodeArray> bytecode_array) {
187 const int kPointerSize = sizeof(void*);
188 int frame_size = bytecode_array->frame_size();
189
190 DCHECK_EQ(frame_size % kPointerSize, 0);
191 stream << "frame size: " << frame_size / kPointerSize;
192 if (frame_size > 0) stream << " # in multiples of sizeof(void*)";
193 stream << "\nparameter count: " << bytecode_array->parameter_count() << '\n';
194 }
195
196 void PrintBytecodeSequence(std::ostream& stream,
197 i::Handle<i::BytecodeArray> bytecode_array) {
198 stream << "bytecodes: [\n";
199 BytecodeArrayIterator bytecode_iter{bytecode_array};
200 for (; !bytecode_iter.done(); bytecode_iter.Advance()) {
201 stream << " ";
202 PrintBytecode(stream, bytecode_iter);
203 stream << ",\n";
204 }
205 stream << "]\n";
206 }
207
208 void PrintConstantPool(std::ostream& stream, i::FixedArray* constant_pool,
209 ConstantPoolType const_pool_type, v8::Isolate* isolate) {
210 stream << "constant pool: [\n";
211 int num_constants = constant_pool->length();
212 if (num_constants > 0) {
213 for (int i = 0; i < num_constants; ++i) {
214 stream << " ";
215 PrintConstant(
216 stream, const_pool_type,
217 i::FixedArray::get(constant_pool, i, GetInternalIsolate(isolate)));
218 stream << ",\n";
219 }
220 }
221 stream << "]\n";
222 }
223
224 void PrintCodeSnippet(std::ostream& stream, const std::string& body) {
225 stream << "snippet: \"\n";
226 std::stringstream body_stream{body};
227 std::string body_line;
228 while (std::getline(body_stream, body_line)) {
229 stream << " ";
230 PrintEscapedString(stream, body_line);
231 stream << '\n';
232 }
233 stream << "\"\n";
234 }
235
236 void PrintBytecodeArray(std::ostream& stream,
237 i::Handle<i::BytecodeArray> bytecode_array,
238 const std::string& body, v8::Isolate* isolate,
239 ConstantPoolType constant_pool_type) {
240 stream << "---\n";
241 PrintCodeSnippet(stream, body);
242 PrintFrameSize(stream, bytecode_array);
243 PrintBytecodeSequence(stream, bytecode_array);
244 PrintConstantPool(stream, bytecode_array->constant_pool(), constant_pool_type,
245 isolate);
246
247 // TODO(ssanfilippo) print handlers.
248 i::HandlerTable* handlers =
249 i::HandlerTable::cast(bytecode_array->handler_table());
250 CHECK_EQ(handlers->NumberOfRangeEntries(), 0);
251 }
252
253 } // namespace
254
255 namespace v8 {
256 namespace internal {
257 namespace interpreter {
258
259 void ExpectationPrinter::PrintExpectation(std::ostream& stream,
260 const std::string& snippet) {
261 const char* wrapper_function_name = "__genbckexp_wrapper__";
262
263 std::string source_code = WrapCodeInFunction(wrapper_function_name, snippet);
264 CompileAndRun(isolate_, source_code.c_str());
265
266 i::Handle<i::BytecodeArray> bytecode_array =
267 GetBytecodeArrayForGlobal(isolate_, wrapper_function_name);
268
269 PrintBytecodeArray(stream, bytecode_array, snippet, isolate_,
270 const_pool_type_);
271 stream << '\n';
272 }
273
274 } // namespace interpreter
275 } // namespace internal
276 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698