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 |