| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 switch (location_) { | 214 switch (location_) { |
| 215 case kAccumulator: | 215 case kAccumulator: |
| 216 if (!reg.is(result_register())) __ movq(result_register(), reg); | 216 if (!reg.is(result_register())) __ movq(result_register(), reg); |
| 217 break; | 217 break; |
| 218 case kStack: | 218 case kStack: |
| 219 __ push(reg); | 219 __ push(reg); |
| 220 break; | 220 break; |
| 221 } | 221 } |
| 222 break; | 222 break; |
| 223 | 223 |
| 224 case Expression::kValueTest: | |
| 225 case Expression::kTestValue: | |
| 226 // Push an extra copy of the value in case it's needed. | |
| 227 __ push(reg); | |
| 228 // Fall through. | |
| 229 | |
| 230 case Expression::kTest: | 224 case Expression::kTest: |
| 231 // For simplicity we always test the accumulator register. | 225 // For simplicity we always test the accumulator register. |
| 232 if (!reg.is(result_register())) __ movq(result_register(), reg); | 226 if (!reg.is(result_register())) __ movq(result_register(), reg); |
| 233 DoTest(context); | 227 DoTest(context); |
| 234 break; | 228 break; |
| 229 |
| 230 case Expression::kValueTest: |
| 231 case Expression::kTestValue: |
| 232 if (!reg.is(result_register())) __ movq(result_register(), reg); |
| 233 switch (location_) { |
| 234 case kAccumulator: |
| 235 break; |
| 236 case kStack: |
| 237 __ push(result_register()); |
| 238 break; |
| 239 } |
| 240 DoTest(context); |
| 241 break; |
| 235 } | 242 } |
| 236 } | 243 } |
| 237 | 244 |
| 238 | 245 |
| 239 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) { | 246 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) { |
| 240 switch (context) { | 247 switch (context) { |
| 241 case Expression::kUninitialized: | 248 case Expression::kUninitialized: |
| 242 UNREACHABLE(); | 249 UNREACHABLE(); |
| 243 case Expression::kEffect: | 250 case Expression::kEffect: |
| 244 // Nothing to do. | 251 // Nothing to do. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 258 } | 265 } |
| 259 | 266 |
| 260 case Expression::kTest: | 267 case Expression::kTest: |
| 261 Move(result_register(), slot); | 268 Move(result_register(), slot); |
| 262 DoTest(context); | 269 DoTest(context); |
| 263 break; | 270 break; |
| 264 | 271 |
| 265 case Expression::kValueTest: | 272 case Expression::kValueTest: |
| 266 case Expression::kTestValue: | 273 case Expression::kTestValue: |
| 267 Move(result_register(), slot); | 274 Move(result_register(), slot); |
| 268 __ push(result_register()); | 275 switch (location_) { |
| 276 case kAccumulator: |
| 277 break; |
| 278 case kStack: |
| 279 __ push(result_register()); |
| 280 break; |
| 281 } |
| 269 DoTest(context); | 282 DoTest(context); |
| 270 break; | 283 break; |
| 271 } | 284 } |
| 272 } | 285 } |
| 273 | 286 |
| 274 | 287 |
| 275 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) { | 288 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) { |
| 276 switch (context) { | 289 switch (context) { |
| 277 case Expression::kUninitialized: | 290 case Expression::kUninitialized: |
| 278 UNREACHABLE(); | 291 UNREACHABLE(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 291 break; | 304 break; |
| 292 | 305 |
| 293 case Expression::kTest: | 306 case Expression::kTest: |
| 294 __ Move(result_register(), lit->handle()); | 307 __ Move(result_register(), lit->handle()); |
| 295 DoTest(context); | 308 DoTest(context); |
| 296 break; | 309 break; |
| 297 | 310 |
| 298 case Expression::kValueTest: | 311 case Expression::kValueTest: |
| 299 case Expression::kTestValue: | 312 case Expression::kTestValue: |
| 300 __ Move(result_register(), lit->handle()); | 313 __ Move(result_register(), lit->handle()); |
| 301 __ push(result_register()); | 314 switch (location_) { |
| 315 case kAccumulator: |
| 316 break; |
| 317 case kStack: |
| 318 __ push(result_register()); |
| 319 break; |
| 320 } |
| 302 DoTest(context); | 321 DoTest(context); |
| 303 break; | 322 break; |
| 304 } | 323 } |
| 305 } | 324 } |
| 306 | 325 |
| 307 | 326 |
| 308 void FastCodeGenerator::ApplyTOS(Expression::Context context) { | 327 void FastCodeGenerator::ApplyTOS(Expression::Context context) { |
| 309 switch (context) { | 328 switch (context) { |
| 310 case Expression::kUninitialized: | 329 case Expression::kUninitialized: |
| 311 UNREACHABLE(); | 330 UNREACHABLE(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 324 } | 343 } |
| 325 break; | 344 break; |
| 326 | 345 |
| 327 case Expression::kTest: | 346 case Expression::kTest: |
| 328 __ pop(result_register()); | 347 __ pop(result_register()); |
| 329 DoTest(context); | 348 DoTest(context); |
| 330 break; | 349 break; |
| 331 | 350 |
| 332 case Expression::kValueTest: | 351 case Expression::kValueTest: |
| 333 case Expression::kTestValue: | 352 case Expression::kTestValue: |
| 334 __ movq(result_register(), Operand(rsp, 0)); | 353 switch (location_) { |
| 354 case kAccumulator: |
| 355 __ pop(result_register()); |
| 356 break; |
| 357 case kStack: |
| 358 __ movq(result_register(), Operand(rsp, 0)); |
| 359 break; |
| 360 } |
| 335 DoTest(context); | 361 DoTest(context); |
| 336 break; | 362 break; |
| 337 } | 363 } |
| 338 } | 364 } |
| 339 | 365 |
| 340 | 366 |
| 341 void FastCodeGenerator::DropAndApply(int count, | 367 void FastCodeGenerator::DropAndApply(int count, |
| 342 Expression::Context context, | 368 Expression::Context context, |
| 343 Register reg) { | 369 Register reg) { |
| 344 ASSERT(count > 0); | 370 ASSERT(count > 0); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 365 break; | 391 break; |
| 366 | 392 |
| 367 case Expression::kTest: | 393 case Expression::kTest: |
| 368 __ Drop(count); | 394 __ Drop(count); |
| 369 if (!reg.is(result_register())) __ movq(result_register(), reg); | 395 if (!reg.is(result_register())) __ movq(result_register(), reg); |
| 370 DoTest(context); | 396 DoTest(context); |
| 371 break; | 397 break; |
| 372 | 398 |
| 373 case Expression::kValueTest: | 399 case Expression::kValueTest: |
| 374 case Expression::kTestValue: | 400 case Expression::kTestValue: |
| 375 if (count > 1) __ Drop(count - 1); | 401 switch (location_) { |
| 376 if (!reg.is(result_register())) __ movq(result_register(), reg); | 402 case kAccumulator: |
| 377 __ movq(Operand(rsp, 0), result_register()); | 403 __ Drop(count); |
| 404 if (!reg.is(result_register())) __ movq(result_register(), reg); |
| 405 break; |
| 406 case kStack: |
| 407 if (count > 1) __ Drop(count - 1); |
| 408 __ movq(result_register(), reg); |
| 409 __ movq(Operand(rsp, 0), result_register()); |
| 410 break; |
| 411 } |
| 378 DoTest(context); | 412 DoTest(context); |
| 379 break; | 413 break; |
| 380 } | 414 } |
| 381 } | 415 } |
| 382 | 416 |
| 383 | 417 |
| 384 void FastCodeGenerator::Apply(Expression::Context context, | 418 void FastCodeGenerator::Apply(Expression::Context context, |
| 385 Label* materialize_true, | 419 Label* materialize_true, |
| 386 Label* materialize_false) { | 420 Label* materialize_false) { |
| 387 switch (context) { | 421 switch (context) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 __ Push(Factory::false_value()); | 473 __ Push(Factory::false_value()); |
| 440 break; | 474 break; |
| 441 } | 475 } |
| 442 __ jmp(false_label_); | 476 __ jmp(false_label_); |
| 443 break; | 477 break; |
| 444 } | 478 } |
| 445 } | 479 } |
| 446 | 480 |
| 447 | 481 |
| 448 void FastCodeGenerator::DoTest(Expression::Context context) { | 482 void FastCodeGenerator::DoTest(Expression::Context context) { |
| 449 // The value to test is in the accumulator, and duplicated on the stack if | 483 // The value to test is in the accumulator. If the value might be needed |
| 450 // necessary (for value/test and test/value contexts). | 484 // on the stack (value/test and test/value contexts with a stack location |
| 485 // desired), then the value is already duplicated on the stack. |
| 451 ASSERT_NE(NULL, true_label_); | 486 ASSERT_NE(NULL, true_label_); |
| 452 ASSERT_NE(NULL, false_label_); | 487 ASSERT_NE(NULL, false_label_); |
| 453 | 488 |
| 454 // If there is a value on the stack, use a discard label for the | 489 // In value/test and test/value expression contexts with stack as the |
| 455 // value-is-unneeded branch in the inlined part of the test. | 490 // desired location, there is already an extra value on the stack. Use a |
| 491 // label to discard it if unneeded. |
| 456 Label discard; | 492 Label discard; |
| 457 Label* if_true = | 493 Label* if_true = true_label_; |
| 458 (context == Expression::kTestValue) ? &discard : true_label_; | 494 Label* if_false = false_label_; |
| 459 Label* if_false = | 495 switch (context) { |
| 460 (context == Expression::kValueTest) ? &discard : false_label_; | 496 case Expression::kUninitialized: |
| 497 case Expression::kEffect: |
| 498 case Expression::kValue: |
| 499 UNREACHABLE(); |
| 500 case Expression::kTest: |
| 501 break; |
| 502 case Expression::kValueTest: |
| 503 switch (location_) { |
| 504 case kAccumulator: |
| 505 break; |
| 506 case kStack: |
| 507 if_false = &discard; |
| 508 break; |
| 509 } |
| 510 break; |
| 511 case Expression::kTestValue: |
| 512 switch (location_) { |
| 513 case kAccumulator: |
| 514 break; |
| 515 case kStack: |
| 516 if_true = &discard; |
| 517 break; |
| 518 } |
| 519 break; |
| 520 } |
| 461 | 521 |
| 462 // Emit the inlined tests assumed by the stub. | 522 // Emit the inlined tests assumed by the stub. |
| 463 __ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex); | 523 __ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex); |
| 464 __ j(equal, if_false); | 524 __ j(equal, if_false); |
| 465 __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); | 525 __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); |
| 466 __ j(equal, if_true); | 526 __ j(equal, if_true); |
| 467 __ CompareRoot(result_register(), Heap::kFalseValueRootIndex); | 527 __ CompareRoot(result_register(), Heap::kFalseValueRootIndex); |
| 468 __ j(equal, if_false); | 528 __ j(equal, if_false); |
| 469 ASSERT_EQ(0, kSmiTag); | 529 ASSERT_EQ(0, kSmiTag); |
| 470 __ SmiCompare(result_register(), Smi::FromInt(0)); | 530 __ SmiCompare(result_register(), Smi::FromInt(0)); |
| 471 __ j(equal, if_false); | 531 __ j(equal, if_false); |
| 472 Condition is_smi = masm_->CheckSmi(result_register()); | 532 Condition is_smi = masm_->CheckSmi(result_register()); |
| 473 __ j(is_smi, if_true); | 533 __ j(is_smi, if_true); |
| 474 | 534 |
| 535 // Save a copy of the value if it may be needed and isn't already saved. |
| 536 switch (context) { |
| 537 case Expression::kUninitialized: |
| 538 case Expression::kEffect: |
| 539 case Expression::kValue: |
| 540 UNREACHABLE(); |
| 541 case Expression::kTest: |
| 542 break; |
| 543 case Expression::kValueTest: |
| 544 switch (location_) { |
| 545 case kAccumulator: |
| 546 __ push(result_register()); |
| 547 break; |
| 548 case kStack: |
| 549 break; |
| 550 } |
| 551 break; |
| 552 case Expression::kTestValue: |
| 553 switch (location_) { |
| 554 case kAccumulator: |
| 555 __ push(result_register()); |
| 556 break; |
| 557 case kStack: |
| 558 break; |
| 559 } |
| 560 break; |
| 561 } |
| 562 |
| 475 // Call the ToBoolean stub for all other cases. | 563 // Call the ToBoolean stub for all other cases. |
| 476 ToBooleanStub stub; | 564 ToBooleanStub stub; |
| 477 __ push(result_register()); | 565 __ push(result_register()); |
| 478 __ CallStub(&stub); | 566 __ CallStub(&stub); |
| 479 __ testq(rax, rax); | 567 __ testq(rax, rax); |
| 480 | 568 |
| 481 // The stub returns nonzero for true. Complete based on the context. | 569 // The stub returns nonzero for true. Complete based on the context. |
| 482 switch (context) { | 570 switch (context) { |
| 483 case Expression::kUninitialized: | 571 case Expression::kUninitialized: |
| 484 case Expression::kEffect: | 572 case Expression::kEffect: |
| (...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1722 __ movq(Operand(rsp, 0), rdx); | 1810 __ movq(Operand(rsp, 0), rdx); |
| 1723 // And return. | 1811 // And return. |
| 1724 __ ret(0); | 1812 __ ret(0); |
| 1725 } | 1813 } |
| 1726 | 1814 |
| 1727 | 1815 |
| 1728 #undef __ | 1816 #undef __ |
| 1729 | 1817 |
| 1730 | 1818 |
| 1731 } } // namespace v8::internal | 1819 } } // namespace v8::internal |
| OLD | NEW |