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

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

Issue 1343363002: [Interpreter] Basic flow control. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Incorporate comments in https://codereview.chromium.org/1343363002/#msg10 Created 5 years, 2 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 }; 57 };
58 58
59 59
60 // Structure for containing expected bytecode snippets. 60 // Structure for containing expected bytecode snippets.
61 template<typename T> 61 template<typename T>
62 struct ExpectedSnippet { 62 struct ExpectedSnippet {
63 const char* code_snippet; 63 const char* code_snippet;
64 int frame_size; 64 int frame_size;
65 int parameter_count; 65 int parameter_count;
66 int bytecode_length; 66 int bytecode_length;
67 const uint8_t bytecode[32]; 67 const uint8_t bytecode[512];
68 int constant_count; 68 int constant_count;
69 T constants[16]; 69 T constants[16];
70 }; 70 };
71 71
72 72
73 // Helper macros for handcrafting bytecode sequences. 73 // Helper macros for handcrafting bytecode sequences.
74 #define B(x) static_cast<uint8_t>(Bytecode::k##x) 74 #define B(x) static_cast<uint8_t>(Bytecode::k##x)
75 #define U8(x) static_cast<uint8_t>((x) & 0xff) 75 #define U8(x) static_cast<uint8_t>((x) & 0xff)
76 #define R(x) static_cast<uint8_t>(-(x) & 0xff) 76 #define R(x) static_cast<uint8_t>(-(x) & 0xff)
77 77
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 CHECK_EQ(ba->frame_size(), snippets[i].frame_size); 178 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
179 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count); 179 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
180 CHECK_EQ(ba->length(), snippets[i].bytecode_length); 180 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
181 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, 181 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
182 ba->length())); 182 ba->length()));
183 CHECK_EQ(ba->constant_pool(), CcTest::heap()->empty_fixed_array()); 183 CHECK_EQ(ba->constant_pool(), CcTest::heap()->empty_fixed_array());
184 } 184 }
185 } 185 }
186 186
187 187
188 TEST(Constants) { 188 TEST(IntegerConstants) {
189 InitializedHandleScope handle_scope; 189 InitializedHandleScope handle_scope;
190 BytecodeGeneratorHelper helper; 190 BytecodeGeneratorHelper helper;
191 191
192 // Check large SMIs. 192 ExpectedSnippet<int> snippets[] = {{"return 12345678;",
193 { 193 0,
194 ExpectedSnippet<int> snippets[] = { 194 1,
195 {"return 12345678;", 0, 1, 3, 195 3,
196 { 196 {
197 B(LdaConstant), U8(0), 197 B(LdaConstant), U8(0), //
198 B(Return) 198 B(Return) //
199 }, 1, { 12345678 } 199 },
200 }, 200 1,
201 {"var a = 1234; return 5678;", 1 * kPointerSize, 1, 7, 201 {12345678}},
202 { 202 {"var a = 1234; return 5678;",
203 B(LdaConstant), U8(0), 203 1 * kPointerSize,
204 B(Star), R(0), 204 1,
205 B(LdaConstant), U8(1), 205 7,
206 B(Return) 206 {
207 }, 2, { 1234, 5678 } 207 B(LdaConstant), U8(0), //
208 }, 208 B(Star), R(0), //
209 {"var a = 1234; return 1234;", 209 B(LdaConstant), U8(1), //
210 1 * kPointerSize, 1, 7, 210 B(Return) //
211 { 211 },
212 B(LdaConstant), U8(0), 212 2,
213 B(Star), R(0), 213 {1234, 5678}},
214 B(LdaConstant), U8(0), 214 {"var a = 1234; return 1234;",
215 B(Return) 215 1 * kPointerSize,
216 }, 1, { 1234 } 216 1,
217 } 217 7,
218 }; 218 {
219 B(LdaConstant), U8(0), //
220 B(Star), R(0), //
221 B(LdaConstant), U8(0), //
222 B(Return) //
223 },
224 1,
225 {1234}}};
rmcilroy 2015/09/24 11:44:36 was this reformat intended?
219 226
220 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 227 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
221 for (size_t i = 0; i < num_snippets; i++) { 228 for (size_t i = 0; i < num_snippets; i++) {
222 Handle<BytecodeArray> ba = 229 Handle<BytecodeArray> ba =
223 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 230 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
224 CHECK_EQ(ba->frame_size(), snippets[i].frame_size); 231 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
225 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count); 232 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
226 CHECK_EQ(ba->length(), snippets[i].bytecode_length); 233 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
227 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, 234 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
228 ba->length())); 235 ba->length()));
229 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count); 236 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
230 for (int j = 0; j < snippets[i].constant_count; j++) { 237 for (int j = 0; j < snippets[i].constant_count; j++) {
231 CHECK_EQ(Smi::cast(ba->constant_pool()->get(j))->value(), 238 CHECK_EQ(Smi::cast(ba->constant_pool()->get(j))->value(),
232 snippets[i].constants[j]); 239 snippets[i].constants[j]);
233 }
234 }
235 }
236
237 // Check heap number double constants
238 {
239 ExpectedSnippet<double> snippets[] = {
240 {"return 1.2;",
241 0, 1, 3,
242 {
243 B(LdaConstant), U8(0),
244 B(Return)
245 }, 1, { 1.2 }
246 },
247 {"var a = 1.2; return 2.6;", 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, { 1.2, 2.6 }
254 },
255 {"var a = 3.14; return 3.14;", 1 * kPointerSize, 1, 7,
256 {
257 B(LdaConstant), U8(0),
258 B(Star), R(0),
259 B(LdaConstant), U8(1),
260 B(Return)
261 }, 2,
262 // TODO(rmcilroy): Currently multiple identical double literals end up
263 // being allocated as new HeapNumbers and so require multiple constant
264 // pool entries. De-dup identical values.
265 { 3.14, 3.14 }
266 }
267 };
268
269 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
270 for (size_t i = 0; i < num_snippets; i++) {
271 Handle<BytecodeArray> ba =
272 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
273 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
274 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
275 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
276 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
277 ba->length()));
278 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
279 for (int j = 0; j < snippets[i].constant_count; j++) {
280 CHECK_EQ(HeapNumber::cast(ba->constant_pool()->get(j))->value(),
281 snippets[i].constants[j]);
282 }
283 }
284 }
285
286 // Check string literals
287 {
288 ExpectedSnippet<const char*> snippets[] = {
289 {"return \"This is a string\";", 0, 1, 3,
290 {
291 B(LdaConstant), U8(0),
292 B(Return)
293 }, 1,
294 { "This is a string" }
295 },
296 {"var a = \"First string\"; return \"Second string\";",
297 1 * kPointerSize, 1, 7,
298 {
299 B(LdaConstant), U8(0),
300 B(Star), R(0),
301 B(LdaConstant), U8(1),
302 B(Return)
303 }, 2, { "First string", "Second string"}
304 },
305 {"var a = \"Same string\"; return \"Same string\";",
306 1 * kPointerSize, 1, 7,
307 {
308 B(LdaConstant), U8(0),
309 B(Star), R(0),
310 B(LdaConstant), U8(0),
311 B(Return)
312 }, 1, { "Same string" }
313 }
314 };
315
316 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
317 for (size_t i = 0; i < num_snippets; i++) {
318 Handle<BytecodeArray> ba =
319 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
320 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
321 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
322 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
323 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
324 ba->length()));
325 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
326 for (int j = 0; j < snippets[i].constant_count; j++) {
327 Handle<String> expected = helper.factory()->NewStringFromAsciiChecked(
328 snippets[i].constants[j]);
329 CHECK(String::cast(ba->constant_pool()->get(j))->Equals(*expected));
330 }
331 } 240 }
332 } 241 }
333 } 242 }
243
244
245 TEST(HeapNumberConstants) {
246 InitializedHandleScope handle_scope;
247 BytecodeGeneratorHelper helper;
248
249 ExpectedSnippet<double> snippets[] = {
250 {"return 1.2;",
251 0,
252 1,
253 3,
254 {
255 B(LdaConstant), U8(0), //
256 B(Return) //
257 },
258 1,
259 {1.2}},
260 {"var a = 1.2; return 2.6;",
261 1 * kPointerSize,
262 1,
263 7,
264 {
265 B(LdaConstant), U8(0), //
266 B(Star), R(0), //
267 B(LdaConstant), U8(1), //
268 B(Return) //
269 },
270 2,
271 {1.2, 2.6}},
272 {"var a = 3.14; return 3.14;",
273 1 * kPointerSize,
274 1,
275 7,
276 {
277 B(LdaConstant), U8(0), //
278 B(Star), R(0), //
279 B(LdaConstant), U8(1), //
280 B(Return) //
281 },
282 2,
283 // TODO(rmcilroy): Currently multiple identical double literals end up
284 // being allocated as new HeapNumbers and so require multiple constant
285 // pool entries. De-dup identical values.
286 {3.14, 3.14}}};
287
288 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
289 for (size_t i = 0; i < num_snippets; i++) {
290 Handle<BytecodeArray> ba =
291 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
292 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
293 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
294 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
295 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
296 ba->length()));
297 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
298 for (int j = 0; j < snippets[i].constant_count; j++) {
299 CHECK_EQ(HeapNumber::cast(ba->constant_pool()->get(j))->value(),
300 snippets[i].constants[j]);
301 }
302 }
303 }
304
305
306 TEST(StringConstants) {
307 InitializedHandleScope handle_scope;
308 BytecodeGeneratorHelper helper;
309
310 ExpectedSnippet<const char*> snippets[] = {
311 {"return \"This is a string\";",
312 0,
313 1,
314 3,
315 {
316 B(LdaConstant), U8(0), //
317 B(Return) //
318 },
319 1,
320 {"This is a string"}},
321 {"var a = \"First string\"; return \"Second string\";",
322 1 * kPointerSize,
323 1,
324 7,
325 {
326 B(LdaConstant), U8(0), //
327 B(Star), R(0), //
328 B(LdaConstant), U8(1), //
329 B(Return) //
330 },
331 2,
332 {"First string", "Second string"}},
333 {"var a = \"Same string\"; return \"Same string\";",
334 1 * kPointerSize,
335 1,
336 7,
337 {
338 B(LdaConstant), U8(0), //
339 B(Star), R(0), //
340 B(LdaConstant), U8(0), //
341 B(Return) //
342 },
343 1,
344 {"Same string"}}};
345
346 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
347 for (size_t i = 0; i < num_snippets; i++) {
348 Handle<BytecodeArray> ba =
349 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
350 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
351 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
352 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
353 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
354 ba->length()));
355 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
356 for (int j = 0; j < snippets[i].constant_count; j++) {
357 Handle<String> expected =
358 helper.factory()->NewStringFromAsciiChecked(snippets[i].constants[j]);
359 CHECK(String::cast(ba->constant_pool()->get(j))->Equals(*expected));
360 }
361 }
362 }
334 363
335 364
336 TEST(PropertyLoads) { 365 TEST(PropertyLoads) {
337 InitializedHandleScope handle_scope; 366 InitializedHandleScope handle_scope;
338 BytecodeGeneratorHelper helper; 367 BytecodeGeneratorHelper helper;
339 368
340 Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC }; 369 Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC };
341 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds); 370 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
342 Handle<i::TypeFeedbackVector> vector = 371 Handle<i::TypeFeedbackVector> vector =
343 helper.factory()->NewTypeFeedbackVector(&feedback_spec); 372 helper.factory()->NewTypeFeedbackVector(&feedback_spec);
344 373
345 ExpectedSnippet<const char*> snippets[] = { 374 ExpectedSnippet<const char*> snippets[] = {
346 {"function f(a) { return a.name; }\nf({name : \"test\"})", 375 {"function f(a) { return a.name; }\nf({name : \"test\"})",
347 1 * kPointerSize, 2, 10, 376 1 * kPointerSize,
377 2,
378 10,
348 { 379 {
349 B(Ldar), R(helper.kLastParamIndex), 380 B(Ldar), R(helper.kLastParamIndex), //
350 B(Star), R(0), 381 B(Star), R(0), //
351 B(LdaConstant), U8(0), 382 B(LdaConstant), U8(0), //
352 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), 383 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), //
353 B(Return) 384 B(Return) //
354 }, 385 },
355 1, { "name" } 386 1,
356 }, 387 {"name"}},
357 {"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})", 388 {"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})",
358 1 * kPointerSize, 2, 10, 389 1 * kPointerSize,
390 2,
391 10,
359 { 392 {
360 B(Ldar), R(helper.kLastParamIndex), 393 B(Ldar), R(helper.kLastParamIndex), //
361 B(Star), R(0), 394 B(Star), R(0), //
362 B(LdaConstant), U8(0), 395 B(LdaConstant), U8(0), //
363 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), 396 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), //
364 B(Return) 397 B(Return) //
365 }, 398 },
366 1, { "key" } 399 1,
367 }, 400 {"key"}},
368 {"function f(a) { return a[100]; }\nf({100 : \"test\"})", 401 {"function f(a) { return a[100]; }\nf({100 : \"test\"})",
369 1 * kPointerSize, 2, 10, 402 1 * kPointerSize,
403 2,
404 10,
370 { 405 {
371 B(Ldar), R(helper.kLastParamIndex), 406 B(Ldar), R(helper.kLastParamIndex), //
372 B(Star), R(0), 407 B(Star), R(0), //
373 B(LdaSmi8), U8(100), 408 B(LdaSmi8), U8(100), //
374 B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), 409 B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), //
375 B(Return) 410 B(Return) //
376 }, 0 411 },
377 }, 412 0},
378 {"function f(a, b) { return a[b]; }\nf({arg : \"test\"}, \"arg\")", 413 {"function f(a, b) { return a[b]; }\nf({arg : \"test\"}, \"arg\")",
379 1 * kPointerSize, 3, 10, 414 1 * kPointerSize,
415 3,
416 10,
380 { 417 {
381 B(Ldar), R(helper.kLastParamIndex - 1), 418 B(Ldar), R(helper.kLastParamIndex - 1), //
382 B(Star), R(0), 419 B(Star), R(0), //
383 B(Ldar), R(helper.kLastParamIndex), 420 B(Ldar), R(helper.kLastParamIndex), //
384 B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), 421 B(KeyedLoadIC), R(0), U8(vector->first_ic_slot_index()), //
385 B(Return) 422 B(Return) //
386 }, 0 423 },
387 }, 424 0},
388 {"function f(a) { var b = a.name; return a[-124]; }\n" 425 {"function f(a) { var b = a.name; return a[-124]; }\n"
389 "f({\"-124\" : \"test\", name : 123 })", 426 "f({\"-124\" : \"test\", name : 123 })",
390 2 * kPointerSize, 2, 21, 427 2 * kPointerSize,
428 2,
429 21,
391 { 430 {
392 B(Ldar), R(helper.kLastParamIndex), 431 B(Ldar), R(helper.kLastParamIndex), //
393 B(Star), R(1), 432 B(Star), R(1), //
394 B(LdaConstant), U8(0), 433 B(LdaConstant), U8(0), //
395 B(LoadIC), R(1), U8(vector->first_ic_slot_index()), 434 B(LoadIC), R(1), U8(vector->first_ic_slot_index()), //
396 B(Star), R(0), 435 B(Star), R(0), //
397 B(Ldar), R(helper.kLastParamIndex), 436 B(Ldar), R(helper.kLastParamIndex), //
398 B(Star), R(1), 437 B(Star), R(1), //
399 B(LdaSmi8), U8(-124), 438 B(LdaSmi8), U8(-124), //
400 B(KeyedLoadIC), R(1), U8(vector->first_ic_slot_index() + 2), 439 B(KeyedLoadIC), R(1), U8(vector->first_ic_slot_index() + 2), //
401 B(Return) 440 B(Return) //
402 }, 441 },
403 1, { "name" } 442 1,
404 } 443 {"name"}}};
405 };
406 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 444 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
407 for (size_t i = 0; i < num_snippets; i++) { 445 for (size_t i = 0; i < num_snippets; i++) {
408 Handle<BytecodeArray> ba = 446 Handle<BytecodeArray> ba =
409 helper.MakeBytecode(snippets[i].code_snippet, "f"); 447 helper.MakeBytecode(snippets[i].code_snippet, "f");
410 CHECK_EQ(ba->frame_size(), snippets[i].frame_size); 448 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
411 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count); 449 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
412 CHECK_EQ(ba->length(), snippets[i].bytecode_length); 450 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
413 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, 451 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
414 ba->length())); 452 ba->length()));
415 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count); 453 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
(...skipping 10 matching lines...) Expand all
426 InitializedHandleScope handle_scope; 464 InitializedHandleScope handle_scope;
427 BytecodeGeneratorHelper helper; 465 BytecodeGeneratorHelper helper;
428 466
429 Code::Kind ic_kinds[] = { i::Code::STORE_IC, i::Code::STORE_IC }; 467 Code::Kind ic_kinds[] = { i::Code::STORE_IC, i::Code::STORE_IC };
430 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds); 468 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
431 Handle<i::TypeFeedbackVector> vector = 469 Handle<i::TypeFeedbackVector> vector =
432 helper.factory()->NewTypeFeedbackVector(&feedback_spec); 470 helper.factory()->NewTypeFeedbackVector(&feedback_spec);
433 471
434 ExpectedSnippet<const char*> snippets[] = { 472 ExpectedSnippet<const char*> snippets[] = {
435 {"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})", 473 {"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})",
436 2 * kPointerSize, 2, 16, 474 2 * kPointerSize,
475 2,
476 16,
437 { 477 {
438 B(Ldar), R(helper.kLastParamIndex), 478 B(Ldar), R(helper.kLastParamIndex), //
439 B(Star), R(0), 479 B(Star), R(0), //
440 B(LdaConstant), U8(0), 480 B(LdaConstant), U8(0), //
441 B(Star), R(1), 481 B(Star), R(1), //
442 B(LdaConstant), U8(1), 482 B(LdaConstant), U8(1), //
443 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), 483 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), //
444 B(LdaUndefined), 484 B(LdaUndefined), //
445 B(Return) 485 B(Return) //
446 }, 486 },
447 2, { "name", "val" } 487 2,
448 }, 488 {"name", "val"}},
449 {"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})", 489 {"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})",
450 2 * kPointerSize, 2, 16, 490 2 * kPointerSize,
491 2,
492 16,
451 { 493 {
452 B(Ldar), R(helper.kLastParamIndex), 494 B(Ldar), R(helper.kLastParamIndex), //
453 B(Star), R(0), 495 B(Star), R(0), //
454 B(LdaConstant), U8(0), 496 B(LdaConstant), U8(0), //
455 B(Star), R(1), 497 B(Star), R(1), //
456 B(LdaConstant), U8(1), 498 B(LdaConstant), U8(1), //
457 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), 499 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), //
458 B(LdaUndefined), 500 B(LdaUndefined), //
459 B(Return) 501 B(Return) //
460 }, 502 },
461 2, { "key", "val" } 503 2,
462 }, 504 {"key", "val"}},
463 {"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})", 505 {"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})",
464 2 * kPointerSize, 2, 16, 506 2 * kPointerSize,
507 2,
508 16,
465 { 509 {
466 B(Ldar), R(helper.kLastParamIndex), 510 B(Ldar), R(helper.kLastParamIndex), //
467 B(Star), R(0), 511 B(Star), R(0), //
468 B(LdaSmi8), U8(100), 512 B(LdaSmi8), U8(100), //
469 B(Star), R(1), 513 B(Star), R(1), //
470 B(LdaConstant), U8(0), 514 B(LdaConstant), U8(0), //
471 B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), 515 B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), //
472 B(LdaUndefined), 516 B(LdaUndefined), //
473 B(Return) 517 B(Return) //
474 }, 518 },
475 1, { "val" } 519 1,
476 }, 520 {"val"}},
477 {"function f(a, b) { a[b] = \"val\"; }\nf({arg : \"test\"}, \"arg\")", 521 {"function f(a, b) { a[b] = \"val\"; }\nf({arg : \"test\"}, \"arg\")",
478 2 * kPointerSize, 3, 16, 522 2 * kPointerSize,
523 3,
524 16,
479 { 525 {
480 B(Ldar), R(helper.kLastParamIndex - 1), 526 B(Ldar), R(helper.kLastParamIndex - 1), //
481 B(Star), R(0), 527 B(Star), R(0), //
482 B(Ldar), R(helper.kLastParamIndex), 528 B(Ldar), R(helper.kLastParamIndex), //
483 B(Star), R(1), 529 B(Star), R(1), //
484 B(LdaConstant), U8(0), 530 B(LdaConstant), U8(0), //
485 B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), 531 B(KeyedStoreIC), R(0), R(1), U8(vector->first_ic_slot_index()), //
486 B(LdaUndefined), 532 B(LdaUndefined), //
487 B(Return) 533 B(Return) //
488 }, 534 },
489 1, { "val" } 535 1,
490 }, 536 {"val"}},
491 {"function f(a) { a.name = a[-124]; }\n" 537 {"function f(a) { a.name = a[-124]; }\n"
492 "f({\"-124\" : \"test\", name : 123 })", 538 "f({\"-124\" : \"test\", name : 123 })",
493 3 * kPointerSize, 2, 23, 539 3 * kPointerSize,
540 2,
541 23,
494 { 542 {
495 B(Ldar), R(helper.kLastParamIndex), 543 B(Ldar), R(helper.kLastParamIndex), //
496 B(Star), R(0), 544 B(Star), R(0), //
497 B(LdaConstant), U8(0), 545 B(LdaConstant), U8(0), //
498 B(Star), R(1), 546 B(Star), R(1), //
499 B(Ldar), R(helper.kLastParamIndex), 547 B(Ldar), R(helper.kLastParamIndex), //
500 B(Star), R(2), 548 B(Star), R(2), //
501 B(LdaSmi8), U8(-124), 549 B(LdaSmi8), U8(-124), //
502 B(KeyedLoadIC), R(2), U8(vector->first_ic_slot_index()), 550 B(KeyedLoadIC), R(2), U8(vector->first_ic_slot_index()), //
503 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index() + 2), 551 B(StoreIC), R(0), R(1), U8(vector->first_ic_slot_index() + 2), //
504 B(LdaUndefined), 552 B(LdaUndefined), //
505 B(Return) 553 B(Return) //
506 }, 554 },
507 1, { "name" } 555 1,
508 } 556 {"name"}}};
509 };
510 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 557 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
511 for (size_t i = 0; i < num_snippets; i++) { 558 for (size_t i = 0; i < num_snippets; i++) {
512 Handle<BytecodeArray> ba = 559 Handle<BytecodeArray> ba =
513 helper.MakeBytecode(snippets[i].code_snippet, "f"); 560 helper.MakeBytecode(snippets[i].code_snippet, "f");
514 CHECK_EQ(ba->frame_size(), snippets[i].frame_size); 561 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
515 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count); 562 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
516 CHECK_EQ(ba->length(), snippets[i].bytecode_length); 563 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
517 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, 564 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
518 ba->length())); 565 ba->length()));
519 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count); 566 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
520 for (int j = 0; j < snippets[i].constant_count; j++) { 567 for (int j = 0; j < snippets[i].constant_count; j++) {
521 Handle<String> expected = 568 Handle<String> expected =
522 helper.factory()->NewStringFromAsciiChecked(snippets[i].constants[j]); 569 helper.factory()->NewStringFromAsciiChecked(snippets[i].constants[j]);
523 CHECK(String::cast(ba->constant_pool()->get(j))->Equals(*expected)); 570 CHECK(String::cast(ba->constant_pool()->get(j))->Equals(*expected));
524 } 571 }
525 } 572 }
526 } 573 }
527 574
528 575
529 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()" 576 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()"
530 577
531 578
532 TEST(PropertyCall) { 579 TEST(PropertyCall) {
533 InitializedHandleScope handle_scope; 580 InitializedHandleScope handle_scope;
534 BytecodeGeneratorHelper helper; 581 BytecodeGeneratorHelper helper; //
535 582
536 Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC }; 583 Code::Kind ic_kinds[] = { i::Code::LOAD_IC, i::Code::LOAD_IC };
537 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds); 584 FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
538 Handle<i::TypeFeedbackVector> vector = 585 Handle<i::TypeFeedbackVector> vector =
539 helper.factory()->NewTypeFeedbackVector(&feedback_spec); 586 helper.factory()->NewTypeFeedbackVector(&feedback_spec);
540 587
541 ExpectedSnippet<const char*> snippets[] = { 588 ExpectedSnippet<const char*> snippets[] = {
542 {"function f(a) { return a.func(); }\nf(" FUNC_ARG ")", 589 {"function f(a) { return a.func(); }\nf(" FUNC_ARG ")",
543 2 * kPointerSize, 2, 16, 590 2 * kPointerSize,
591 2,
592 16,
544 { 593 {
545 B(Ldar), R(helper.kLastParamIndex), 594 B(Ldar), R(helper.kLastParamIndex), //
546 B(Star), R(1), 595 B(Star), R(1), //
547 B(LdaConstant), U8(0), 596 B(LdaConstant), U8(0), //
548 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), 597 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), //
549 B(Star), R(0), 598 B(Star), R(0), //
550 B(Call), R(0), R(1), U8(0), 599 B(Call), R(0), R(1), U8(0), //
551 B(Return) 600 B(Return) //
552 }, 601 },
553 1, { "func" } 602 1,
554 }, 603 {"func"}},
555 {"function f(a, b, c) { return a.func(b, c); }\nf(" FUNC_ARG ", 1, 2)", 604 {"function f(a, b, c) { return a.func(b, c); }\nf(" FUNC_ARG ", 1, 2)",
556 4 * kPointerSize, 4, 24, 605 4 * kPointerSize,
606 4,
607 24,
557 { 608 {
558 B(Ldar), R(helper.kLastParamIndex - 2), 609 B(Ldar), R(helper.kLastParamIndex - 2), //
559 B(Star), R(1), 610 B(Star), R(1), //
560 B(LdaConstant), U8(0), 611 B(LdaConstant), U8(0), //
561 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), 612 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), //
562 B(Star), R(0), 613 B(Star), R(0), //
563 B(Ldar), R(helper.kLastParamIndex - 1), 614 B(Ldar), R(helper.kLastParamIndex - 1), //
564 B(Star), R(2), 615 B(Star), R(2), //
565 B(Ldar), R(helper.kLastParamIndex), 616 B(Ldar), R(helper.kLastParamIndex), //
566 B(Star), R(3), 617 B(Star), R(3), //
567 B(Call), R(0), R(1), U8(2), 618 B(Call), R(0), R(1), U8(2), //
568 B(Return) 619 B(Return) //
569 }, 620 },
570 1, { "func" } 621 1,
571 }, 622 {"func"}},
572 {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)", 623 {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)",
573 4 * kPointerSize, 3, 30, 624 4 * kPointerSize,
574 { 625 3,
575 B(Ldar), R(helper.kLastParamIndex - 1), 626 30,
576 B(Star), R(1), 627 {
577 B(LdaConstant), U8(0), 628 B(Ldar), R(helper.kLastParamIndex - 1), //
578 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), 629 B(Star), R(1), //
579 B(Star), R(0), 630 B(LdaConstant), U8(0), //
580 B(Ldar), R(helper.kLastParamIndex), 631 B(LoadIC), R(1), U8(vector->first_ic_slot_index() + 2), //
581 B(Star), R(2), 632 B(Star), R(0), //
582 B(Ldar), R(helper.kLastParamIndex), 633 B(Ldar), R(helper.kLastParamIndex), //
583 B(Add), R(2), 634 B(Star), R(2), //
584 B(Star), R(2), 635 B(Ldar), R(helper.kLastParamIndex), //
585 B(Ldar), R(helper.kLastParamIndex), 636 B(Add), R(2), //
586 B(Star), R(3), 637 B(Star), R(2), //
587 B(Call), R(0), R(1), U8(2), 638 B(Ldar), R(helper.kLastParamIndex), //
588 B(Return) 639 B(Star), R(3), //
640 B(Call), R(0), R(1), U8(2), //
641 B(Return) //
rmcilroy 2015/09/24 11:44:36 Thanks for fixing all these other tests!
589 }, 642 },
590 1, { "func" } 643 1,
591 } 644 {"func"}}};
592 };
593 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 645 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
594 for (size_t i = 0; i < num_snippets; i++) { 646 for (size_t i = 0; i < num_snippets; i++) {
595 Handle<BytecodeArray> ba = 647 Handle<BytecodeArray> ba =
596 helper.MakeBytecode(snippets[i].code_snippet, "f"); 648 helper.MakeBytecode(snippets[i].code_snippet, "f");
597 CHECK_EQ(ba->frame_size(), snippets[i].frame_size); 649 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
598 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count); 650 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
599 CHECK_EQ(ba->length(), snippets[i].bytecode_length); 651 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
600 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, 652 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
601 ba->length())); 653 ba->length()));
602 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count); 654 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
603 for (int j = 0; j < snippets[i].constant_count; j++) { 655 for (int j = 0; j < snippets[i].constant_count; j++) {
604 Handle<String> expected = 656 Handle<String> expected =
605 helper.factory()->NewStringFromAsciiChecked(snippets[i].constants[j]); 657 helper.factory()->NewStringFromAsciiChecked(snippets[i].constants[j]);
606 CHECK(String::cast(ba->constant_pool()->get(j))->Equals(*expected)); 658 CHECK(String::cast(ba->constant_pool()->get(j))->Equals(*expected));
607 } 659 }
608 } 660 }
609 } 661 }
610 662
663
664 TEST(IfConditions) {
665 InitializedHandleScope handle_scope;
666 BytecodeGeneratorHelper helper;
667
668 ExpectedSnippet<void*> snippets[] = {
669 {"function f() { if (0) { return 1; } else { return -1; } }",
670 0,
671 1,
672 14,
673 {B(LdaZero), //
674 B(ToBoolean), //
675 B(JumpIfFalse), U8(7), //
676 B(LdaSmi8), U8(1), //
677 B(Return), //
678 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
679 B(LdaSmi8), U8(-1), //
680 B(Return), //
681 B(LdaUndefined), //
682 B(Return)}, //
683 0},
684 {"function f() { if ('lucky') { return 1; } else { return -1; } }",
685 0,
686 1,
687 15,
688 {B(LdaConstant), U8(0), //
689 B(ToBoolean), //
690 B(JumpIfFalse), U8(7), //
691 B(LdaSmi8), U8(1), //
692 B(Return), //
693 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
694 B(LdaSmi8), U8(-1), //
695 B(Return), //
696 B(LdaUndefined), //
697 B(Return)}, //
698 1},
699 {"function f() { if (false) { return 1; } else { return -1; } }",
700 0,
701 1,
702 13,
703 {B(LdaFalse), //
704 B(JumpIfFalse), U8(7), //
705 B(LdaSmi8), U8(1), //
706 B(Return), //
707 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
708 B(LdaSmi8), U8(-1), //
709 B(Return), //
710 B(LdaUndefined), //
711 B(Return)}, //
712 0},
713 {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }",
714 kPointerSize,
715 2,
716 19,
717 {B(Ldar), R(-5), //
718 B(Star), R(0), //
719 B(LdaZero), //
720 B(TestLessThanEqual), R(0), //
721 B(JumpIfFalse), U8(7), //
722 B(LdaConstant), U8(0), //
723 B(Return), //
724 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
725 B(LdaConstant), U8(1), //
726 B(Return), //
727 B(LdaUndefined), //
728 B(Return)}, //
729 2},
730 {"function f(a, b) { if (a in b) { return 200; } }",
731 kPointerSize,
732 3,
733 17,
734 {B(Ldar), R(-6), //
735 B(Star), R(0), //
736 B(Ldar), R(-5), //
737 B(TestIn), R(0), //
738 B(JumpIfFalse), U8(7), //
739 B(LdaConstant), U8(0), //
740 B(Return), //
741 B(Jump), U8(2), // TODO(oth): Unreachable jump after return
742 B(LdaUndefined), //
743 B(Return)}, //
744 1},
745 {"function f(a, b) { if (a instanceof b) { return 200; } }",
746 kPointerSize,
747 3,
748 17,
749 {B(Ldar), R(-6), //
750 B(Star), R(0), //
751 B(Ldar), R(-5), //
752 B(TestInstanceOf), R(0), //
753 B(JumpIfFalse), U8(7), //
754 B(LdaConstant), U8(0), //
755 B(Return), //
756 B(Jump), U8(2), // TODO(oth): Unreachable jump after return
757 B(LdaUndefined), //
758 B(Return)}, //
759 1},
760 {"function f(z) { var a = 0; var b = 0; if (a === 0.01) { "
761 #define X "b = a; a = b; "
762 X X X X X X X X X X X X X X X X X X X X X X X X
763 #undef X
764 " return 200; } else { return -200; } }",
765 3 * kPointerSize,
766 2,
767 218,
768 {B(LdaZero), //
769 B(Star), R(0), //
770 B(LdaZero), //
771 B(Star), R(1), //
772 B(Ldar), R(0), //
773 B(Star), R(2), //
774 B(LdaConstant), U8(0), //
775 B(TestEqualStrict), R(2), //
776 B(JumpIfFalseConstant), U8(2), //
777 #define X B(Ldar), R(0), B(Star), R(1), B(Ldar), R(1), B(Star), R(0),
778 X X X X X X X X X X X X X X X X X X X X X X X X
779 #undef X
780 B(LdaConstant),
781 U8(1), //
782 B(Return), //
783 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
784 B(LdaConstant), U8(3), //
785 B(Return), //
786 B(LdaUndefined), //
787 B(Return)}, //
788 4}, //
789 };
790
791 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
792 for (size_t i = 0; i < num_snippets; i++) {
793 Handle<BytecodeArray> ba =
794 helper.MakeBytecodeForFunction(snippets[i].code_snippet);
795 CHECK_EQ(ba->frame_size(), snippets[i].frame_size);
796 CHECK_EQ(ba->parameter_count(), snippets[i].parameter_count);
797 CHECK_EQ(ba->length(), snippets[i].bytecode_length);
798 CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode,
799 ba->length()));
800 CHECK_EQ(ba->constant_pool()->length(), snippets[i].constant_count);
801 }
802 }
803
804
611 } // namespace interpreter 805 } // namespace interpreter
612 } // namespace internal 806 } // namespace internal
613 } // namespance v8 807 } // namespance v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698