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

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

Issue 1321663003: [Interpreter] Add support for loading literals from the constant pool. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_const_pool_1
Patch Set: Created 5 years, 3 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
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/bytecode-generator.h" 8 #include "src/interpreter/bytecode-generator.h"
9 #include "src/interpreter/interpreter.h" 9 #include "src/interpreter/interpreter.h"
10 #include "test/cctest/cctest.h" 10 #include "test/cctest/cctest.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 43
44 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { 44 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) {
45 ScopedVector<char> program(1024); 45 ScopedVector<char> program(1024);
46 SNPrintF(program, "%s\n%s();", function, kFunctionName); 46 SNPrintF(program, "%s\n%s();", function, kFunctionName);
47 return MakeBytecode(program.start(), kFunctionName); 47 return MakeBytecode(program.start(), kFunctionName);
48 } 48 }
49 }; 49 };
50 50
51 51
52 // Structure for containing expected bytecode snippets. 52 // Structure for containing expected bytecode snippets.
53 template<typename T>
53 struct ExpectedSnippet { 54 struct ExpectedSnippet {
54 const char* body; 55 const char* body;
55 int frame_size; 56 int frame_size;
56 int parameter_count; 57 int parameter_count;
57 int bytecode_length; 58 int bytecode_length;
58 const uint8_t bytecode[16]; 59 const uint8_t bytecode[16];
60 int constant_count;
61 T constants[16];
59 }; 62 };
60 63
61 64
62 // Helper macros for handcrafting bytecode sequences. 65 // Helper macros for handcrafting bytecode sequences.
63 #define B(x) static_cast<uint8_t>(Bytecode::k##x) 66 #define B(x) static_cast<uint8_t>(Bytecode::k##x)
64 #define U8(x) static_cast<uint8_t>((x) & 0xff) 67 #define U8(x) static_cast<uint8_t>((x) & 0xff)
65 #define R(x) static_cast<uint8_t>(-(x) & 0xff) 68 #define R(x) static_cast<uint8_t>(-(x) & 0xff)
66 69
67 70
68 TEST(PrimitiveReturnStatements) { 71 TEST(PrimitiveReturnStatements) {
69 InitializedHandleScope handle_scope; 72 InitializedHandleScope handle_scope;
70 BytecodeGeneratorHelper helper; 73 BytecodeGeneratorHelper helper;
71 74
72 ExpectedSnippet snippets[] = { 75 ExpectedSnippet<void*> snippets[] = {
73 {"return;", 0, 1, 2, {B(LdaUndefined), B(Return)}}, 76 {"return;", 0, 1, 2, {B(LdaUndefined), B(Return)}, 0},
74 {"return null;", 0, 1, 2, {B(LdaNull), B(Return)}}, 77 {"return null;", 0, 1, 2, {B(LdaNull), B(Return)}, 0},
75 {"return true;", 0, 1, 2, {B(LdaTrue), B(Return)}}, 78 {"return true;", 0, 1, 2, {B(LdaTrue), B(Return)}, 0},
76 {"return false;", 0, 1, 2, {B(LdaFalse), B(Return)}}, 79 {"return false;", 0, 1, 2, {B(LdaFalse), B(Return)}, 0},
77 {"return 0;", 0, 1, 2, {B(LdaZero), B(Return)}}, 80 {"return 0;", 0, 1, 2, {B(LdaZero), B(Return)}, 0},
78 {"return +1;", 0, 1, 3, {B(LdaSmi8), U8(1), B(Return)}}, 81 {"return +1;", 0, 1, 3, {B(LdaSmi8), U8(1), B(Return)}, 0},
79 {"return -1;", 0, 1, 3, {B(LdaSmi8), U8(-1), B(Return)}}, 82 {"return -1;", 0, 1, 3, {B(LdaSmi8), U8(-1), B(Return)}, 0},
80 {"return +127;", 0, 1, 3, {B(LdaSmi8), U8(127), B(Return)}}, 83 {"return +127;", 0, 1, 3, {B(LdaSmi8), U8(127), B(Return)}, 0},
81 {"return -128;", 0, 1, 3, {B(LdaSmi8), U8(-128), B(Return)}}, 84 {"return -128;", 0, 1, 3, {B(LdaSmi8), U8(-128), B(Return)}, 0},
82 }; 85 };
83 86
84 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 87 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
85 for (size_t i = 0; i < num_snippets; i++) { 88 for (size_t i = 0; i < num_snippets; i++) {
86 Handle<BytecodeArray> ba = 89 Handle<BytecodeArray> ba =
87 helper.MakeBytecodeForFunctionBody(snippets[i].body); 90 helper.MakeBytecodeForFunctionBody(snippets[i].body);
88 CHECK_EQ(ba->frame_size(), snippets[i].frame_size); 91 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
89 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count); 92 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
90 CHECK_EQ(ba->length(), snippets[i].bytecode_length); 93 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
91 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, 94 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
92 ba->length())); 95 ba->length()));
96 CHECK_EQ(ba->constant_pool(), CcTest::heap()->empty_fixed_array());
93 } 97 }
94 } 98 }
95 99
96 100
97 TEST(PrimitiveExpressions) { 101 TEST(PrimitiveExpressions) {
98 InitializedHandleScope handle_scope; 102 InitializedHandleScope handle_scope;
99 BytecodeGeneratorHelper helper; 103 BytecodeGeneratorHelper helper;
100 104
101 ExpectedSnippet snippets[] = { 105 ExpectedSnippet<void*> snippets[] = {
102 {"var x = 0; return x;", 106 {"var x = 0; return x;",
103 kPointerSize, 107 kPointerSize,
104 1, 108 1,
105 6, 109 6,
106 { 110 {
107 B(LdaZero), // 111 B(LdaZero), //
108 B(Star), R(0), // 112 B(Star), R(0), //
109 B(Ldar), R(0), // 113 B(Ldar), R(0), //
110 B(Return) // 114 B(Return) //
111 }}, 115 },
116 0
117 },
112 {"var x = 0; return x + 3;", 118 {"var x = 0; return x + 3;",
113 2 * kPointerSize, 119 2 * kPointerSize,
114 1, 120 1,
115 12, 121 12,
116 { 122 {
117 B(LdaZero), // 123 B(LdaZero), //
118 B(Star), R(0), // 124 B(Star), R(0), //
119 B(Ldar), R(0), // Easy to spot r1 not really needed here. 125 B(Ldar), R(0), // Easy to spot r1 not really needed here.
120 B(Star), R(1), // Dead store. 126 B(Star), R(1), // Dead store.
121 B(LdaSmi8), U8(3), // 127 B(LdaSmi8), U8(3), //
122 B(Add), R(1), // 128 B(Add), R(1), //
123 B(Return) // 129 B(Return) //
124 }}}; 130 },
131 0
132 }};
125 133
126 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 134 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
127 for (size_t i = 0; i < num_snippets; i++) { 135 for (size_t i = 0; i < num_snippets; i++) {
128 Handle<BytecodeArray> ba = 136 Handle<BytecodeArray> ba =
129 helper.MakeBytecodeForFunctionBody(snippets[i].body); 137 helper.MakeBytecodeForFunctionBody(snippets[i].body);
130 CHECK_EQ(ba->frame_size(), snippets[i].frame_size); 138 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
131 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count); 139 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
132 CHECK_EQ(ba->length(), snippets[i].bytecode_length); 140 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
133 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, 141 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
134 ba->length())); 142 ba->length()));
143 CHECK_EQ(ba->constant_pool(), CcTest::heap()->empty_fixed_array());
135 } 144 }
136 } 145 }
137 146
138 147
139 TEST(Parameters) { 148 TEST(Parameters) {
140 InitializedHandleScope handle_scope; 149 InitializedHandleScope handle_scope;
141 BytecodeGeneratorHelper helper; 150 BytecodeGeneratorHelper helper;
142 151
143 int last_param_index = 152 int last_param_index =
144 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; 153 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize;
145 ExpectedSnippet snippets[] = { 154 ExpectedSnippet<void*> snippets[] = {
146 {"function f() { return this; }", 155 {"function f() { return this; }",
147 0, 1, 3, {B(Ldar), R(last_param_index), B(Return)}}, 156 0, 1, 3, {B(Ldar), R(last_param_index), B(Return)}, 0},
148 {"function f(arg1) { return arg1; }", 157 {"function f(arg1) { return arg1; }",
149 0, 2, 3, {B(Ldar), R(last_param_index), B(Return)}}, 158 0, 2, 3, {B(Ldar), R(last_param_index), B(Return)}, 0},
150 {"function f(arg1) { return this; }", 159 {"function f(arg1) { return this; }",
151 0, 2, 3, {B(Ldar), R(last_param_index - 1), B(Return)}}, 160 0, 2, 3, {B(Ldar), R(last_param_index - 1), B(Return)}, 0},
152 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }", 161 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }",
153 0, 8, 3, {B(Ldar), R(last_param_index - 3), B(Return)}}, 162 0, 8, 3, {B(Ldar), R(last_param_index - 3), B(Return)}, 0},
154 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }", 163 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }",
155 0, 8, 3, {B(Ldar), R(last_param_index - 7), B(Return)}} 164 0, 8, 3, {B(Ldar), R(last_param_index - 7), B(Return)}, 0}
156 }; 165 };
157 166
158 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 167 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
159 for (size_t i = 0; i < num_snippets; i++) { 168 for (size_t i = 0; i < num_snippets; i++) {
160 Handle<BytecodeArray> ba = helper.MakeBytecodeForFunction(snippets[i].body); 169 Handle<BytecodeArray> ba = helper.MakeBytecodeForFunction(snippets[i].body);
161 CHECK_EQ(ba->frame_size(), snippets[i].frame_size); 170 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
162 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count); 171 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
163 CHECK_EQ(ba->length(), snippets[i].bytecode_length); 172 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
164 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, 173 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
165 ba->length())); 174 ba->length()));
175 CHECK_EQ(ba->constant_pool(), CcTest::heap()->empty_fixed_array());
166 } 176 }
167 } 177 }
168 178
179
180 TEST(Constants) {
181 InitializedHandleScope handle_scope;
182 BytecodeGeneratorHelper helper;
183
184 // Check large SMIs.
185 {
186 ExpectedSnippet<int> snippets[] = {
187 {"return 12345678;", 0, 1, 3,
188 {
189 B(LdaConstant), U8(0),
190 B(Return)
191 }, 1, { 12345678 }
192 },
193 {"var a = 1234; return 5678;", 1 * kPointerSize, 1, 7,
194 {
195 B(LdaConstant), U8(0),
196 B(Star), R(0),
197 B(LdaConstant), U8(1),
198 B(Return)
199 }, 2, { 1234, 5678 }
200 },
201 {"var a = 1234; return 1234;",
202 1 * kPointerSize, 1, 7,
203 {
204 B(LdaConstant), U8(0),
205 B(Star), R(0),
206 B(LdaConstant), U8(0),
207 B(Return)
208 }, 1, { 1234 }
209 }
210 };
211
212 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
213 for (size_t i = 0; i < num_snippets; i++) {
214 Handle<BytecodeArray> ba =
215 helper.MakeBytecodeForFunctionBody(snippets[i].body);
216 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
217 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
218 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
219 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
220 ba->length()));
221 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
222 for (int j = 0; j < snippets[i].constant_count; j++) {
223 CHECK_EQ(Smi::cast(ba->constant_pool()->get(j))->value(),
224 snippets[i].constants[j]);
225 }
226 }
227 }
228
229 // Check heap number double constants
230 {
231 ExpectedSnippet<double> snippets[] = {
232 {"return 1.2;",
233 0, 1, 3,
234 {
235 B(LdaConstant), U8(0),
236 B(Return)
237 }, 1, { 1.2 }
238 },
239 {"var a = 1.2; return 2.6;", 1 * kPointerSize, 1, 7,
240 {
241 B(LdaConstant), U8(0),
242 B(Star), R(0),
243 B(LdaConstant), U8(1),
244 B(Return)
245 }, 2, { 1.2, 2.6 }
246 },
247 {"var a = 3.14; return 3.14;", 1 * kPointerSize, 1, 7,
248 {
249 B(LdaConstant), U8(0),
250 B(Star), R(0),
251 B(LdaConstant), U8(1),
252 B(Return)
253 }, 2,
254 // TODO(rmcilroy): Currently multiple identical double literals end up
255 // being allocated as new HeapNumbers and so require multiple constant
256 // pool entries. De-dup identical values.
257 { 3.14, 3.14 }
rmcilroy 2015/08/27 16:34:07 Michi - looks like double literals aren't de-duped
Michael Starzinger 2015/08/27 19:36:29 Not sure I understand your comment correctly. How
Michael Starzinger 2015/08/27 19:55:36 Ah, I think now I understand where you are coming
258 }
259 };
260
261 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
262 for (size_t i = 0; i < num_snippets; i++) {
263 Handle<BytecodeArray> ba =
264 helper.MakeBytecodeForFunctionBody(snippets[i].body);
265 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
266 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
267 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
268 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
269 ba->length()));
270 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
271 for (int j = 0; j < snippets[i].constant_count; j++) {
272 CHECK_EQ(HeapNumber::cast(ba->constant_pool()->get(j))->value(),
273 snippets[i].constants[j]);
274 }
275 }
276 }
277
278 // Check string literals
279 {
280 ExpectedSnippet<const char*> snippets[] = {
281 {"return \"This is a string\";", 0, 1, 3,
282 {
283 B(LdaConstant), U8(0),
284 B(Return)
285 }, 1,
286 { "This is a string" }
287 },
288 {"var a = \"First string\"; return \"Second string\";",
289 1 * kPointerSize, 1, 7,
290 {
291 B(LdaConstant), U8(0),
292 B(Star), R(0),
293 B(LdaConstant), U8(1),
294 B(Return)
295 }, 2, { "First string", "Second string"}
296 },
297 {"var a = \"Same string\"; return \"Same string\";",
298 1 * kPointerSize, 1, 7,
299 {
300 B(LdaConstant), U8(0),
301 B(Star), R(0),
302 B(LdaConstant), U8(0),
303 B(Return)
304 }, 1, { "Same string" }
305 }
306 };
307
308 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
309 for (size_t i = 0; i < num_snippets; i++) {
310 Handle<BytecodeArray> ba =
311 helper.MakeBytecodeForFunctionBody(snippets[i].body);
312 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
313 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
314 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
315 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
316 ba->length()));
317 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
318 for (int j = 0; j < snippets[i].constant_count; j++) {
319 Handle<String> expected =
320 CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(
321 snippets[i].constants[j]);
322 CHECK(String::cast(ba->constant_pool()->get(j))->Equals(*expected));
323 }
324 }
325 }
326 }
327
328
169 } // namespace interpreter 329 } // namespace interpreter
170 } // namespace internal 330 } // namespace internal
171 } // namespance v8 331 } // namespance v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698