| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 int MinorKey() { return 0; } | 333 int MinorKey() { return 0; } |
| 334 }; | 334 }; |
| 335 | 335 |
| 336 | 336 |
| 337 enum NegativeZeroHandling { | 337 enum NegativeZeroHandling { |
| 338 kStrictNegativeZero, | 338 kStrictNegativeZero, |
| 339 kIgnoreNegativeZero | 339 kIgnoreNegativeZero |
| 340 }; | 340 }; |
| 341 | 341 |
| 342 | 342 |
| 343 enum UnaryOpFlags { |
| 344 NO_UNARY_FLAGS = 0, |
| 345 NO_UNARY_SMI_CODE_IN_STUB = 1 << 0 |
| 346 }; |
| 347 |
| 348 |
| 343 class GenericUnaryOpStub : public CodeStub { | 349 class GenericUnaryOpStub : public CodeStub { |
| 344 public: | 350 public: |
| 345 GenericUnaryOpStub(Token::Value op, | 351 GenericUnaryOpStub(Token::Value op, |
| 346 UnaryOverwriteMode overwrite, | 352 UnaryOverwriteMode overwrite, |
| 353 UnaryOpFlags flags, |
| 347 NegativeZeroHandling negative_zero = kStrictNegativeZero) | 354 NegativeZeroHandling negative_zero = kStrictNegativeZero) |
| 348 : op_(op), overwrite_(overwrite), negative_zero_(negative_zero) { } | 355 : op_(op), |
| 356 overwrite_(overwrite), |
| 357 include_smi_code_((flags & NO_UNARY_SMI_CODE_IN_STUB) == 0), |
| 358 negative_zero_(negative_zero) { } |
| 349 | 359 |
| 350 private: | 360 private: |
| 351 Token::Value op_; | 361 Token::Value op_; |
| 352 UnaryOverwriteMode overwrite_; | 362 UnaryOverwriteMode overwrite_; |
| 363 bool include_smi_code_; |
| 353 NegativeZeroHandling negative_zero_; | 364 NegativeZeroHandling negative_zero_; |
| 354 | 365 |
| 355 class OverwriteField: public BitField<UnaryOverwriteMode, 0, 1> {}; | 366 class OverwriteField: public BitField<UnaryOverwriteMode, 0, 1> {}; |
| 356 class NegativeZeroField: public BitField<NegativeZeroHandling, 1, 1> {}; | 367 class IncludeSmiCodeField: public BitField<bool, 1, 1> {}; |
| 357 class OpField: public BitField<Token::Value, 2, kMinorBits - 2> {}; | 368 class NegativeZeroField: public BitField<NegativeZeroHandling, 2, 1> {}; |
| 369 class OpField: public BitField<Token::Value, 3, kMinorBits - 3> {}; |
| 358 | 370 |
| 359 Major MajorKey() { return GenericUnaryOp; } | 371 Major MajorKey() { return GenericUnaryOp; } |
| 360 int MinorKey() { | 372 int MinorKey() { |
| 361 return OpField::encode(op_) | | 373 return OpField::encode(op_) | |
| 362 OverwriteField::encode(overwrite_) | | 374 OverwriteField::encode(overwrite_) | |
| 363 NegativeZeroField::encode(negative_zero_); | 375 IncludeSmiCodeField::encode(include_smi_code_) | |
| 376 NegativeZeroField::encode(negative_zero_); |
| 364 } | 377 } |
| 365 | 378 |
| 366 void Generate(MacroAssembler* masm); | 379 void Generate(MacroAssembler* masm); |
| 367 | 380 |
| 368 const char* GetName(); | 381 const char* GetName(); |
| 369 }; | 382 }; |
| 370 | 383 |
| 371 | 384 |
| 372 enum NaNInformation { | 385 enum NaNInformation { |
| 373 kBothCouldBeNaN, | 386 kBothCouldBeNaN, |
| 374 kCantBothBeNaN | 387 kCantBothBeNaN |
| 375 }; | 388 }; |
| 376 | 389 |
| 377 | 390 |
| 391 // Flags that control the compare stub code generation. |
| 392 enum CompareFlags { |
| 393 NO_COMPARE_FLAGS = 0, |
| 394 NO_SMI_COMPARE_IN_STUB = 1 << 0, |
| 395 NO_NUMBER_COMPARE_IN_STUB = 1 << 1, |
| 396 CANT_BOTH_BE_NAN = 1 << 2 |
| 397 }; |
| 398 |
| 399 |
| 378 class CompareStub: public CodeStub { | 400 class CompareStub: public CodeStub { |
| 379 public: | 401 public: |
| 380 CompareStub(Condition cc, | 402 CompareStub(Condition cc, |
| 381 bool strict, | 403 bool strict, |
| 382 NaNInformation nan_info = kBothCouldBeNaN, | 404 CompareFlags flags, |
| 383 bool include_number_compare = true, | 405 Register lhs, |
| 384 Register lhs = no_reg, | 406 Register rhs) : |
| 385 Register rhs = no_reg) : | |
| 386 cc_(cc), | 407 cc_(cc), |
| 387 strict_(strict), | 408 strict_(strict), |
| 388 never_nan_nan_(nan_info == kCantBothBeNaN), | 409 never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), |
| 389 include_number_compare_(include_number_compare), | 410 include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), |
| 411 include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), |
| 390 lhs_(lhs), | 412 lhs_(lhs), |
| 391 rhs_(rhs), | 413 rhs_(rhs), |
| 392 name_(NULL) { } | 414 name_(NULL) { } |
| 393 | 415 |
| 416 CompareStub(Condition cc, |
| 417 bool strict, |
| 418 CompareFlags flags) : |
| 419 cc_(cc), |
| 420 strict_(strict), |
| 421 never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), |
| 422 include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), |
| 423 include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), |
| 424 lhs_(no_reg), |
| 425 rhs_(no_reg), |
| 426 name_(NULL) { } |
| 427 |
| 394 void Generate(MacroAssembler* masm); | 428 void Generate(MacroAssembler* masm); |
| 395 | 429 |
| 396 private: | 430 private: |
| 397 Condition cc_; | 431 Condition cc_; |
| 398 bool strict_; | 432 bool strict_; |
| 399 // Only used for 'equal' comparisons. Tells the stub that we already know | 433 // Only used for 'equal' comparisons. Tells the stub that we already know |
| 400 // that at least one side of the comparison is not NaN. This allows the | 434 // that at least one side of the comparison is not NaN. This allows the |
| 401 // stub to use object identity in the positive case. We ignore it when | 435 // stub to use object identity in the positive case. We ignore it when |
| 402 // generating the minor key for other comparisons to avoid creating more | 436 // generating the minor key for other comparisons to avoid creating more |
| 403 // stubs. | 437 // stubs. |
| 404 bool never_nan_nan_; | 438 bool never_nan_nan_; |
| 405 // Do generate the number comparison code in the stub. Stubs without number | 439 // Do generate the number comparison code in the stub. Stubs without number |
| 406 // comparison code is used when the number comparison has been inlined, and | 440 // comparison code is used when the number comparison has been inlined, and |
| 407 // the stub will be called if one of the operands is not a number. | 441 // the stub will be called if one of the operands is not a number. |
| 408 bool include_number_compare_; | 442 bool include_number_compare_; |
| 443 |
| 444 // Generate the comparison code for two smi operands in the stub. |
| 445 bool include_smi_compare_; |
| 446 |
| 409 // Register holding the left hand side of the comparison if the stub gives | 447 // Register holding the left hand side of the comparison if the stub gives |
| 410 // a choice, no_reg otherwise. | 448 // a choice, no_reg otherwise. |
| 411 Register lhs_; | 449 Register lhs_; |
| 412 // Register holding the right hand side of the comparison if the stub gives | 450 // Register holding the right hand side of the comparison if the stub gives |
| 413 // a choice, no_reg otherwise. | 451 // a choice, no_reg otherwise. |
| 414 Register rhs_; | 452 Register rhs_; |
| 415 | 453 |
| 416 // Encoding of the minor key CCCCCCCCCCCCRCNS. | 454 // Encoding of the minor key in 16 bits. |
| 417 class StrictField: public BitField<bool, 0, 1> {}; | 455 class StrictField: public BitField<bool, 0, 1> {}; |
| 418 class NeverNanNanField: public BitField<bool, 1, 1> {}; | 456 class NeverNanNanField: public BitField<bool, 1, 1> {}; |
| 419 class IncludeNumberCompareField: public BitField<bool, 2, 1> {}; | 457 class IncludeNumberCompareField: public BitField<bool, 2, 1> {}; |
| 420 class RegisterField: public BitField<bool, 3, 1> {}; | 458 class IncludeSmiCompareField: public BitField<bool, 3, 1> {}; |
| 421 class ConditionField: public BitField<int, 4, 12> {}; | 459 class RegisterField: public BitField<bool, 4, 1> {}; |
| 460 class ConditionField: public BitField<int, 5, 11> {}; |
| 422 | 461 |
| 423 Major MajorKey() { return Compare; } | 462 Major MajorKey() { return Compare; } |
| 424 | 463 |
| 425 int MinorKey(); | 464 int MinorKey(); |
| 426 | 465 |
| 427 // Branch to the label if the given object isn't a symbol. | 466 // Branch to the label if the given object isn't a symbol. |
| 428 void BranchIfNonSymbol(MacroAssembler* masm, | 467 void BranchIfNonSymbol(MacroAssembler* masm, |
| 429 Label* label, | 468 Label* label, |
| 430 Register object, | 469 Register object, |
| 431 Register scratch); | 470 Register scratch); |
| 432 | 471 |
| 433 // Unfortunately you have to run without snapshots to see most of these | 472 // Unfortunately you have to run without snapshots to see most of these |
| 434 // names in the profile since most compare stubs end up in the snapshot. | 473 // names in the profile since most compare stubs end up in the snapshot. |
| 435 char* name_; | 474 char* name_; |
| 436 const char* GetName(); | 475 const char* GetName(); |
| 437 #ifdef DEBUG | 476 #ifdef DEBUG |
| 438 void Print() { | 477 void Print() { |
| 439 PrintF("CompareStub (cc %d), (strict %s), " | 478 PrintF("CompareStub (minor %d) (cc %d), (strict %s), " |
| 440 "(never_nan_nan %s), (number_compare %s) ", | 479 "(never_nan_nan %s), (smi_compare %s) (number_compare %s) ", |
| 480 MinorKey(), |
| 441 static_cast<int>(cc_), | 481 static_cast<int>(cc_), |
| 442 strict_ ? "true" : "false", | 482 strict_ ? "true" : "false", |
| 443 never_nan_nan_ ? "true" : "false", | 483 never_nan_nan_ ? "true" : "false", |
| 484 include_smi_compare_ ? "inluded" : "not included", |
| 444 include_number_compare_ ? "included" : "not included"); | 485 include_number_compare_ ? "included" : "not included"); |
| 445 | 486 |
| 446 if (!lhs_.is(no_reg) && !rhs_.is(no_reg)) { | 487 if (!lhs_.is(no_reg) && !rhs_.is(no_reg)) { |
| 447 PrintF("(lhs r%d), (rhs r%d)\n", lhs_.code(), rhs_.code()); | 488 PrintF("(lhs r%d), (rhs r%d)\n", lhs_.code(), rhs_.code()); |
| 448 } else { | 489 } else { |
| 449 PrintF("\n"); | 490 PrintF("\n"); |
| 450 } | 491 } |
| 451 } | 492 } |
| 452 #endif | 493 #endif |
| 453 }; | 494 }; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 private: | 827 private: |
| 787 StringCharCodeAtGenerator char_code_at_generator_; | 828 StringCharCodeAtGenerator char_code_at_generator_; |
| 788 StringCharFromCodeGenerator char_from_code_generator_; | 829 StringCharFromCodeGenerator char_from_code_generator_; |
| 789 | 830 |
| 790 DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator); | 831 DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator); |
| 791 }; | 832 }; |
| 792 | 833 |
| 793 } } // namespace v8::internal | 834 } } // namespace v8::internal |
| 794 | 835 |
| 795 #endif // V8_CODE_STUBS_H_ | 836 #endif // V8_CODE_STUBS_H_ |
| OLD | NEW |