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

Side by Side Diff: src/compiler/x64/code-generator-x64.cc

Issue 804993004: [turbofan] Fix unsafe out-of-bounds check for checked loads/stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/node-properties-inl.h" 10 #include "src/compiler/node-properties-inl.h"
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 if (instr->InputAt(1)->IsDoubleRegister()) { \ 265 if (instr->InputAt(1)->IsDoubleRegister()) { \
266 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ 266 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
267 i.InputDoubleRegister(1)); \ 267 i.InputDoubleRegister(1)); \
268 } else { \ 268 } else { \
269 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ 269 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
270 i.InputOperand(1)); \ 270 i.InputOperand(1)); \
271 } \ 271 } \
272 } while (0) 272 } while (0)
273 273
274 274
275 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ 275 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \
276 do { \
277 auto result = i.OutputDoubleRegister(); \
278 auto buffer = i.InputRegister(0); \
279 auto index1 = i.InputRegister(1); \
280 auto index2 = i.InputInt32(2); \
281 OutOfLineCode* ool; \
282 if (instr->InputAt(3)->IsRegister()) { \
283 auto length = i.InputRegister(3); \
284 DCHECK_EQ(0, index2); \
285 __ cmpl(index1, length); \
286 ool = new (zone()) OutOfLineLoadNaN(this, result); \
287 } else { \
288 auto length = i.InputInt32(3); \
289 DCHECK_LE(index2, length); \
290 __ cmpq(index1, Immediate(length - index2)); \
291 class OutOfLineLoadFloat FINAL : public OutOfLineCode { \
292 public: \
293 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \
294 Register buffer, Register index1, int32_t index2, \
295 int32_t length) \
296 : OutOfLineCode(gen), \
297 result_(result), \
298 buffer_(buffer), \
299 index1_(index1), \
300 index2_(index2), \
301 length_(length) {} \
302 \
303 void Generate() FINAL { \
304 __ leal(kScratchRegister, Operand(index1_, index2_)); \
305 __ pcmpeqd(result_, result_); \
306 __ cmpl(kScratchRegister, Immediate(length_)); \
307 __ j(above_equal, exit()); \
308 __ asm_instr(result_, \
309 Operand(buffer_, kScratchRegister, times_1, 0)); \
310 } \
311 \
312 private: \
313 XMMRegister const result_; \
314 Register const buffer_; \
315 Register const index1_; \
316 int32_t const index2_; \
317 int32_t const length_; \
318 }; \
319 ool = new (zone()) \
320 OutOfLineLoadFloat(this, result, buffer, index1, index2, length); \
321 } \
322 __ j(above_equal, ool->entry()); \
323 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \
324 __ bind(ool->exit()); \
325 } while (false)
326
327
328 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
276 do { \ 329 do { \
277 auto result = i.OutputDoubleRegister(); \ 330 auto result = i.OutputRegister(); \
278 auto buffer = i.InputRegister(0); \ 331 auto buffer = i.InputRegister(0); \
279 auto index1 = i.InputRegister(1); \ 332 auto index1 = i.InputRegister(1); \
280 auto index2 = i.InputInt32(2); \ 333 auto index2 = i.InputInt32(2); \
281 OutOfLineCode* ool; \ 334 OutOfLineCode* ool; \
282 if (instr->InputAt(3)->IsRegister()) { \ 335 if (instr->InputAt(3)->IsRegister()) { \
283 auto length = i.InputRegister(3); \ 336 auto length = i.InputRegister(3); \
284 DCHECK_EQ(0, index2); \ 337 DCHECK_EQ(0, index2); \
285 __ cmpl(index1, length); \ 338 __ cmpl(index1, length); \
286 ool = new (zone()) OutOfLineLoadNaN(this, result); \ 339 ool = new (zone()) OutOfLineLoadZero(this, result); \
287 } else { \ 340 } else { \
288 auto length = i.InputInt32(3); \ 341 auto length = i.InputInt32(3); \
289 DCHECK_LE(index2, length); \ 342 DCHECK_LE(index2, length); \
290 __ cmpl(index1, Immediate(length - index2)); \ 343 __ cmpq(index1, Immediate(length - index2)); \
291 if (index2 == 0) { \ 344 class OutOfLineLoadInteger FINAL : public OutOfLineCode { \
292 ool = new (zone()) OutOfLineLoadNaN(this, result); \ 345 public: \
293 } else { \ 346 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \
294 class OutOfLineLoadFloat FINAL : public OutOfLineCode { \
295 public: \
296 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \
297 Register buffer, Register index1, int32_t index2, \ 347 Register buffer, Register index1, int32_t index2, \
298 int32_t length) \ 348 int32_t length) \
299 : OutOfLineCode(gen), \ 349 : OutOfLineCode(gen), \
300 result_(result), \ 350 result_(result), \
301 buffer_(buffer), \ 351 buffer_(buffer), \
302 index1_(index1), \ 352 index1_(index1), \
303 index2_(index2), \ 353 index2_(index2), \
304 length_(length) {} \ 354 length_(length) {} \
305 \ 355 \
306 void Generate() FINAL { \ 356 void Generate() FINAL { \
307 DCHECK_NE(0, index2_); \ 357 __ leal(kScratchRegister, Operand(index1_, index2_)); \
308 __ leal(kScratchRegister, Operand(index1_, index2_)); \ 358 __ xorl(result_, result_); \
309 __ pcmpeqd(result_, result_); \ 359 __ cmpl(kScratchRegister, Immediate(length_)); \
310 __ cmpl(kScratchRegister, Immediate(length_)); \ 360 __ j(above_equal, exit()); \
311 __ j(above_equal, exit()); \ 361 __ asm_instr(result_, \
312 __ asm_instr(result_, \ 362 Operand(buffer_, kScratchRegister, times_1, 0)); \
313 Operand(buffer_, kScratchRegister, times_1, 0)); \ 363 } \
314 } \
315 \ 364 \
316 private: \ 365 private: \
317 XMMRegister const result_; \ 366 Register const result_; \
318 Register const buffer_; \ 367 Register const buffer_; \
319 Register const index1_; \ 368 Register const index1_; \
320 int32_t const index2_; \ 369 int32_t const index2_; \
321 int32_t const length_; \ 370 int32_t const length_; \
322 }; \ 371 }; \
323 ool = new (zone()) \ 372 ool = new (zone()) \
324 OutOfLineLoadFloat(this, result, buffer, index1, index2, length); \ 373 OutOfLineLoadInteger(this, result, buffer, index1, index2, length); \
325 } \
326 } \ 374 } \
327 __ j(above_equal, ool->entry()); \ 375 __ j(above_equal, ool->entry()); \
328 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ 376 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \
329 __ bind(ool->exit()); \ 377 __ bind(ool->exit()); \
330 } while (false) 378 } while (false)
331 379
332 380
333 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ 381 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \
334 do { \ 382 do { \
335 auto result = i.OutputRegister(); \ 383 auto buffer = i.InputRegister(0); \
336 auto buffer = i.InputRegister(0); \ 384 auto index1 = i.InputRegister(1); \
337 auto index1 = i.InputRegister(1); \ 385 auto index2 = i.InputInt32(2); \
338 auto index2 = i.InputInt32(2); \ 386 auto value = i.InputDoubleRegister(4); \
339 OutOfLineCode* ool; \ 387 if (instr->InputAt(3)->IsRegister()) { \
340 if (instr->InputAt(3)->IsRegister()) { \ 388 auto length = i.InputRegister(3); \
341 auto length = i.InputRegister(3); \ 389 DCHECK_EQ(0, index2); \
342 DCHECK_EQ(0, index2); \ 390 Label done; \
343 __ cmpl(index1, length); \ 391 __ cmpl(index1, length); \
344 ool = new (zone()) OutOfLineLoadZero(this, result); \ 392 __ j(above_equal, &done, Label::kNear); \
345 } else { \ 393 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
346 auto length = i.InputInt32(3); \ 394 __ bind(&done); \
347 DCHECK_LE(index2, length); \ 395 } else { \
348 __ cmpl(index1, Immediate(length - index2)); \ 396 auto length = i.InputInt32(3); \
349 if (index2 == 0) { \ 397 DCHECK_LE(index2, length); \
350 ool = new (zone()) OutOfLineLoadZero(this, result); \ 398 __ cmpq(index1, Immediate(length - index2)); \
351 } else { \ 399 class OutOfLineStoreFloat FINAL : public OutOfLineCode { \
352 class OutOfLineLoadInteger FINAL : public OutOfLineCode { \ 400 public: \
353 public: \ 401 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \
354 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ 402 Register index1, int32_t index2, int32_t length, \
355 Register buffer, Register index1, \ 403 XMMRegister value) \
356 int32_t index2, int32_t length) \ 404 : OutOfLineCode(gen), \
357 : OutOfLineCode(gen), \ 405 buffer_(buffer), \
358 result_(result), \ 406 index1_(index1), \
359 buffer_(buffer), \ 407 index2_(index2), \
360 index1_(index1), \ 408 length_(length), \
361 index2_(index2), \ 409 value_(value) {} \
362 length_(length) {} \ 410 \
363 \ 411 void Generate() FINAL { \
364 void Generate() FINAL { \ 412 __ leal(kScratchRegister, Operand(index1_, index2_)); \
365 DCHECK_NE(0, index2_); \ 413 __ cmpl(kScratchRegister, Immediate(length_)); \
366 __ leal(kScratchRegister, Operand(index1_, index2_)); \ 414 __ j(above_equal, exit()); \
367 __ xorl(result_, result_); \ 415 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \
368 __ cmpl(kScratchRegister, Immediate(length_)); \ 416 value_); \
369 __ j(above_equal, exit()); \ 417 } \
370 __ asm_instr(result_, \ 418 \
371 Operand(buffer_, kScratchRegister, times_1, 0)); \ 419 private: \
372 } \ 420 Register const buffer_; \
373 \ 421 Register const index1_; \
374 private: \ 422 int32_t const index2_; \
375 Register const result_; \ 423 int32_t const length_; \
376 Register const buffer_; \ 424 XMMRegister const value_; \
377 Register const index1_; \ 425 }; \
378 int32_t const index2_; \ 426 auto ool = new (zone()) \
379 int32_t const length_; \ 427 OutOfLineStoreFloat(this, buffer, index1, index2, length, value); \
380 }; \ 428 __ j(above_equal, ool->entry()); \
381 ool = new (zone()) OutOfLineLoadInteger(this, result, buffer, index1, \ 429 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
382 index2, length); \ 430 __ bind(ool->exit()); \
383 } \ 431 } \
384 } \
385 __ j(above_equal, ool->entry()); \
386 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \
387 __ bind(ool->exit()); \
388 } while (false) 432 } while (false)
389 433
390 434
391 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ 435 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \
392 do { \ 436 do { \
393 auto buffer = i.InputRegister(0); \ 437 auto buffer = i.InputRegister(0); \
394 auto index1 = i.InputRegister(1); \ 438 auto index1 = i.InputRegister(1); \
395 auto index2 = i.InputInt32(2); \ 439 auto index2 = i.InputInt32(2); \
396 auto value = i.InputDoubleRegister(4); \
397 if (instr->InputAt(3)->IsRegister()) { \ 440 if (instr->InputAt(3)->IsRegister()) { \
398 auto length = i.InputRegister(3); \ 441 auto length = i.InputRegister(3); \
399 DCHECK_EQ(0, index2); \ 442 DCHECK_EQ(0, index2); \
400 Label done; \ 443 Label done; \
401 __ cmpl(index1, length); \ 444 __ cmpl(index1, length); \
402 __ j(above_equal, &done, Label::kNear); \ 445 __ j(above_equal, &done, Label::kNear); \
403 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 446 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
404 __ bind(&done); \ 447 __ bind(&done); \
405 } else { \ 448 } else { \
406 auto length = i.InputInt32(3); \ 449 auto length = i.InputInt32(3); \
407 DCHECK_LE(index2, length); \ 450 DCHECK_LE(index2, length); \
408 __ cmpl(index1, Immediate(length - index2)); \ 451 __ cmpq(index1, Immediate(length - index2)); \
409 if (index2 == 0) { \ 452 class OutOfLineStoreInteger FINAL : public OutOfLineCode { \
410 Label done; \ 453 public: \
411 __ j(above_equal, &done, Label::kNear); \ 454 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \
412 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
413 __ bind(&done); \
414 } else { \
415 class OutOfLineStoreFloat FINAL : public OutOfLineCode { \
416 public: \
417 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \
418 Register index1, int32_t index2, int32_t length, \ 455 Register index1, int32_t index2, int32_t length, \
419 XMMRegister value) \ 456 Value value) \
420 : OutOfLineCode(gen), \ 457 : OutOfLineCode(gen), \
421 buffer_(buffer), \ 458 buffer_(buffer), \
422 index1_(index1), \ 459 index1_(index1), \
423 index2_(index2), \ 460 index2_(index2), \
424 length_(length), \ 461 length_(length), \
425 value_(value) {} \ 462 value_(value) {} \
426 \ 463 \
427 void Generate() FINAL { \ 464 void Generate() FINAL { \
428 DCHECK_NE(0, index2_); \ 465 __ leal(kScratchRegister, Operand(index1_, index2_)); \
429 __ leal(kScratchRegister, Operand(index1_, index2_)); \ 466 __ cmpl(kScratchRegister, Immediate(length_)); \
430 __ cmpl(kScratchRegister, Immediate(length_)); \ 467 __ j(above_equal, exit()); \
431 __ j(above_equal, exit()); \ 468 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \
432 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ 469 value_); \
433 value_); \ 470 } \
434 } \
435 \ 471 \
436 private: \ 472 private: \
437 Register const buffer_; \ 473 Register const buffer_; \
438 Register const index1_; \ 474 Register const index1_; \
439 int32_t const index2_; \ 475 int32_t const index2_; \
440 int32_t const length_; \ 476 int32_t const length_; \
441 XMMRegister const value_; \ 477 Value const value_; \
442 }; \ 478 }; \
443 auto ool = new (zone()) \ 479 auto ool = new (zone()) \
444 OutOfLineStoreFloat(this, buffer, index1, index2, length, value); \ 480 OutOfLineStoreInteger(this, buffer, index1, index2, length, value); \
445 __ j(above_equal, ool->entry()); \ 481 __ j(above_equal, ool->entry()); \
446 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 482 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
447 __ bind(ool->exit()); \ 483 __ bind(ool->exit()); \
448 } \
449 } \ 484 } \
450 } while (false) 485 } while (false)
451 486
452 487
453 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \
454 do { \
455 auto buffer = i.InputRegister(0); \
456 auto index1 = i.InputRegister(1); \
457 auto index2 = i.InputInt32(2); \
458 if (instr->InputAt(3)->IsRegister()) { \
459 auto length = i.InputRegister(3); \
460 DCHECK_EQ(0, index2); \
461 Label done; \
462 __ cmpl(index1, length); \
463 __ j(above_equal, &done, Label::kNear); \
464 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
465 __ bind(&done); \
466 } else { \
467 auto length = i.InputInt32(3); \
468 DCHECK_LE(index2, length); \
469 __ cmpl(index1, Immediate(length - index2)); \
470 if (index2 == 0) { \
471 Label done; \
472 __ j(above_equal, &done, Label::kNear); \
473 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
474 __ bind(&done); \
475 } else { \
476 class OutOfLineStoreInteger FINAL : public OutOfLineCode { \
477 public: \
478 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \
479 Register index1, int32_t index2, \
480 int32_t length, Value value) \
481 : OutOfLineCode(gen), \
482 buffer_(buffer), \
483 index1_(index1), \
484 index2_(index2), \
485 length_(length), \
486 value_(value) {} \
487 \
488 void Generate() FINAL { \
489 DCHECK_NE(0, index2_); \
490 __ leal(kScratchRegister, Operand(index1_, index2_)); \
491 __ cmpl(kScratchRegister, Immediate(length_)); \
492 __ j(above_equal, exit()); \
493 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \
494 value_); \
495 } \
496 \
497 private: \
498 Register const buffer_; \
499 Register const index1_; \
500 int32_t const index2_; \
501 int32_t const length_; \
502 Value const value_; \
503 }; \
504 auto ool = new (zone()) OutOfLineStoreInteger(this, buffer, index1, \
505 index2, length, value); \
506 __ j(above_equal, ool->entry()); \
507 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
508 __ bind(ool->exit()); \
509 } \
510 } \
511 } while (false)
512
513
514 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ 488 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
515 do { \ 489 do { \
516 if (instr->InputAt(4)->IsRegister()) { \ 490 if (instr->InputAt(4)->IsRegister()) { \
517 Register value = i.InputRegister(4); \ 491 Register value = i.InputRegister(4); \
518 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ 492 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \
519 } else { \ 493 } else { \
520 Immediate value = i.InputImmediate(4); \ 494 Immediate value = i.InputImmediate(4); \
521 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ 495 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \
522 } \ 496 } \
523 } while (false) 497 } while (false)
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 } 1411 }
1438 } 1412 }
1439 MarkLazyDeoptSite(); 1413 MarkLazyDeoptSite();
1440 } 1414 }
1441 1415
1442 #undef __ 1416 #undef __
1443 1417
1444 } // namespace internal 1418 } // namespace internal
1445 } // namespace compiler 1419 } // namespace compiler
1446 } // namespace v8 1420 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm64/instruction-selector-arm64.cc ('k') | test/mjsunit/compiler/regress-443744.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698