OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 return reinterpret_cast<intptr_t>(raw_address_); | 343 return reinterpret_cast<intptr_t>(raw_address_); |
344 } | 344 } |
345 | 345 |
346 private: | 346 private: |
347 Address raw_address_; | 347 Address raw_address_; |
348 }; | 348 }; |
349 | 349 |
350 | 350 |
351 class HType { | 351 class HType { |
352 public: | 352 public: |
353 HType() : type_(kUninitialized) { } | |
354 | |
355 static HType Tagged() { return HType(kTagged); } | 353 static HType Tagged() { return HType(kTagged); } |
356 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } | 354 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } |
357 static HType TaggedNumber() { return HType(kTaggedNumber); } | 355 static HType TaggedNumber() { return HType(kTaggedNumber); } |
358 static HType Smi() { return HType(kSmi); } | 356 static HType Smi() { return HType(kSmi); } |
359 static HType HeapNumber() { return HType(kHeapNumber); } | 357 static HType HeapNumber() { return HType(kHeapNumber); } |
360 static HType String() { return HType(kString); } | 358 static HType String() { return HType(kString); } |
361 static HType Boolean() { return HType(kBoolean); } | 359 static HType Boolean() { return HType(kBoolean); } |
362 static HType NonPrimitive() { return HType(kNonPrimitive); } | 360 static HType NonPrimitive() { return HType(kNonPrimitive); } |
363 static HType JSArray() { return HType(kJSArray); } | 361 static HType JSArray() { return HType(kJSArray); } |
364 static HType JSObject() { return HType(kJSObject); } | 362 static HType JSObject() { return HType(kJSObject); } |
365 static HType Uninitialized() { return HType(kUninitialized); } | |
366 | 363 |
367 // Return the weakest (least precise) common type. | 364 // Return the weakest (least precise) common type. |
368 HType Combine(HType other) { | 365 HType Combine(HType other) { |
369 return HType(static_cast<Type>(type_ & other.type_)); | 366 return HType(static_cast<Type>(type_ & other.type_)); |
370 } | 367 } |
371 | 368 |
372 bool Equals(const HType& other) const { | 369 bool Equals(const HType& other) const { |
373 return type_ == other.type_; | 370 return type_ == other.type_; |
374 } | 371 } |
375 | 372 |
376 bool IsSubtypeOf(const HType& other) { | 373 bool IsSubtypeOf(const HType& other) { |
377 return Combine(other).Equals(other); | 374 return Combine(other).Equals(other); |
378 } | 375 } |
379 | 376 |
380 bool IsTagged() const { | 377 bool IsTagged() const { |
381 ASSERT(type_ != kUninitialized); | |
382 return ((type_ & kTagged) == kTagged); | 378 return ((type_ & kTagged) == kTagged); |
383 } | 379 } |
384 | 380 |
385 bool IsTaggedPrimitive() const { | 381 bool IsTaggedPrimitive() const { |
386 ASSERT(type_ != kUninitialized); | |
387 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); | 382 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); |
388 } | 383 } |
389 | 384 |
390 bool IsTaggedNumber() const { | 385 bool IsTaggedNumber() const { |
391 ASSERT(type_ != kUninitialized); | |
392 return ((type_ & kTaggedNumber) == kTaggedNumber); | 386 return ((type_ & kTaggedNumber) == kTaggedNumber); |
393 } | 387 } |
394 | 388 |
395 bool IsSmi() const { | 389 bool IsSmi() const { |
396 ASSERT(type_ != kUninitialized); | |
397 return ((type_ & kSmi) == kSmi); | 390 return ((type_ & kSmi) == kSmi); |
398 } | 391 } |
399 | 392 |
400 bool IsHeapNumber() const { | 393 bool IsHeapNumber() const { |
401 ASSERT(type_ != kUninitialized); | |
402 return ((type_ & kHeapNumber) == kHeapNumber); | 394 return ((type_ & kHeapNumber) == kHeapNumber); |
403 } | 395 } |
404 | 396 |
405 bool IsString() const { | 397 bool IsString() const { |
406 ASSERT(type_ != kUninitialized); | |
407 return ((type_ & kString) == kString); | 398 return ((type_ & kString) == kString); |
408 } | 399 } |
409 | 400 |
410 bool IsNonString() const { | 401 bool IsNonString() const { |
411 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || | 402 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || |
412 IsBoolean() || IsJSArray(); | 403 IsBoolean() || IsJSArray(); |
413 } | 404 } |
414 | 405 |
415 bool IsBoolean() const { | 406 bool IsBoolean() const { |
416 ASSERT(type_ != kUninitialized); | |
417 return ((type_ & kBoolean) == kBoolean); | 407 return ((type_ & kBoolean) == kBoolean); |
418 } | 408 } |
419 | 409 |
420 bool IsNonPrimitive() const { | 410 bool IsNonPrimitive() const { |
421 ASSERT(type_ != kUninitialized); | |
422 return ((type_ & kNonPrimitive) == kNonPrimitive); | 411 return ((type_ & kNonPrimitive) == kNonPrimitive); |
423 } | 412 } |
424 | 413 |
425 bool IsJSArray() const { | 414 bool IsJSArray() const { |
426 ASSERT(type_ != kUninitialized); | |
427 return ((type_ & kJSArray) == kJSArray); | 415 return ((type_ & kJSArray) == kJSArray); |
428 } | 416 } |
429 | 417 |
430 bool IsJSObject() const { | 418 bool IsJSObject() const { |
431 ASSERT(type_ != kUninitialized); | |
432 return ((type_ & kJSObject) == kJSObject); | 419 return ((type_ & kJSObject) == kJSObject); |
433 } | 420 } |
434 | 421 |
435 bool IsUninitialized() const { | |
436 return type_ == kUninitialized; | |
437 } | |
438 | |
439 bool IsHeapObject() const { | 422 bool IsHeapObject() const { |
440 ASSERT(type_ != kUninitialized); | |
441 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); | 423 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); |
442 } | 424 } |
443 | 425 |
444 static HType TypeFromValue(Handle<Object> value); | 426 static HType TypeFromValue(Handle<Object> value); |
445 | 427 |
446 const char* ToString(); | 428 const char* ToString(); |
447 | 429 |
448 private: | 430 private: |
449 enum Type { | 431 enum Type { |
450 kTagged = 0x1, // 0000 0000 0000 0001 | 432 kTagged = 0x1, // 0000 0000 0000 0001 |
451 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | 433 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 |
452 kTaggedNumber = 0xd, // 0000 0000 0000 1101 | 434 kTaggedNumber = 0xd, // 0000 0000 0000 1101 |
453 kSmi = 0x1d, // 0000 0000 0001 1101 | 435 kSmi = 0x1d, // 0000 0000 0001 1101 |
454 kHeapNumber = 0x2d, // 0000 0000 0010 1101 | 436 kHeapNumber = 0x2d, // 0000 0000 0010 1101 |
455 kString = 0x45, // 0000 0000 0100 0101 | 437 kString = 0x45, // 0000 0000 0100 0101 |
456 kBoolean = 0x85, // 0000 0000 1000 0101 | 438 kBoolean = 0x85, // 0000 0000 1000 0101 |
457 kNonPrimitive = 0x101, // 0000 0001 0000 0001 | 439 kNonPrimitive = 0x101, // 0000 0001 0000 0001 |
458 kJSObject = 0x301, // 0000 0011 0000 0001 | 440 kJSObject = 0x301, // 0000 0011 0000 0001 |
459 kJSArray = 0x701, // 0000 0111 0000 0001 | 441 kJSArray = 0x701 // 0000 0111 0000 0001 |
460 kUninitialized = 0x1fff // 0001 1111 1111 1111 | |
461 }; | 442 }; |
462 | 443 |
463 // Make sure type fits in int16. | 444 // Make sure type fits in int16. |
464 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte))); | 445 STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte))); |
465 | 446 |
466 explicit HType(Type t) : type_(t) { } | 447 explicit HType(Type t) : type_(t) { } |
467 | 448 |
468 int16_t type_; | 449 int16_t type_; |
469 }; | 450 }; |
470 | 451 |
471 | 452 |
472 class HUseListNode: public ZoneObject { | 453 class HUseListNode: public ZoneObject { |
473 public: | 454 public: |
474 HUseListNode(HValue* value, int index, HUseListNode* tail) | 455 HUseListNode(HValue* value, int index, HUseListNode* tail) |
(...skipping 2448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2923 return Representation::Tagged(); | 2904 return Representation::Tagged(); |
2924 } | 2905 } |
2925 | 2906 |
2926 virtual HType CalculateInferredType(); | 2907 virtual HType CalculateInferredType(); |
2927 | 2908 |
2928 #ifdef DEBUG | 2909 #ifdef DEBUG |
2929 virtual void Verify(); | 2910 virtual void Verify(); |
2930 #endif | 2911 #endif |
2931 | 2912 |
2932 virtual HValue* Canonicalize() { | 2913 virtual HValue* Canonicalize() { |
2933 HType value_type = value()->type(); | 2914 return value()->type().IsHeapObject() ? NULL : this; |
2934 if (!value_type.IsUninitialized() && value_type.IsHeapObject()) { | |
2935 return NULL; | |
2936 } | |
2937 return this; | |
2938 } | 2915 } |
2939 | 2916 |
2940 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) | 2917 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) |
2941 | 2918 |
2942 protected: | 2919 protected: |
2943 virtual bool DataEquals(HValue* other) { return true; } | 2920 virtual bool DataEquals(HValue* other) { return true; } |
2944 }; | 2921 }; |
2945 | 2922 |
2946 | 2923 |
2947 class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 2924 class HCheckPrototypeMaps: public HTemplateInstruction<0> { |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3526 | 3503 |
3527 virtual Representation KnownOptimalRepresentation() { | 3504 virtual Representation KnownOptimalRepresentation() { |
3528 if (HasSmiValue()) return Representation::Smi(); | 3505 if (HasSmiValue()) return Representation::Smi(); |
3529 if (HasInteger32Value()) return Representation::Integer32(); | 3506 if (HasInteger32Value()) return Representation::Integer32(); |
3530 if (HasNumberValue()) return Representation::Double(); | 3507 if (HasNumberValue()) return Representation::Double(); |
3531 return Representation::Tagged(); | 3508 return Representation::Tagged(); |
3532 } | 3509 } |
3533 | 3510 |
3534 virtual bool EmitAtUses(); | 3511 virtual bool EmitAtUses(); |
3535 virtual void PrintDataTo(StringStream* stream); | 3512 virtual void PrintDataTo(StringStream* stream); |
3536 virtual HType CalculateInferredType(); | |
3537 bool IsInteger() { return handle()->IsSmi(); } | 3513 bool IsInteger() { return handle()->IsSmi(); } |
3538 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; | 3514 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
3539 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); | 3515 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); |
3540 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); | 3516 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); |
3541 bool HasInteger32Value() const { return has_int32_value_; } | 3517 bool HasInteger32Value() const { return has_int32_value_; } |
3542 int32_t Integer32Value() const { | 3518 int32_t Integer32Value() const { |
3543 ASSERT(HasInteger32Value()); | 3519 ASSERT(HasInteger32Value()); |
3544 return int32_value_; | 3520 return int32_value_; |
3545 } | 3521 } |
3546 bool HasSmiValue() const { return has_smi_value_; } | 3522 bool HasSmiValue() const { return has_smi_value_; } |
(...skipping 16 matching lines...) Expand all Loading... |
3563 int32_t NumberValueAsInteger32() const { | 3539 int32_t NumberValueAsInteger32() const { |
3564 ASSERT(HasNumberValue()); | 3540 ASSERT(HasNumberValue()); |
3565 // Irrespective of whether a numeric HConstant can be safely | 3541 // Irrespective of whether a numeric HConstant can be safely |
3566 // represented as an int32, we store the (in some cases lossy) | 3542 // represented as an int32, we store the (in some cases lossy) |
3567 // representation of the number in int32_value_. | 3543 // representation of the number in int32_value_. |
3568 return int32_value_; | 3544 return int32_value_; |
3569 } | 3545 } |
3570 bool HasStringValue() const { | 3546 bool HasStringValue() const { |
3571 if (has_double_value_ || has_int32_value_) return false; | 3547 if (has_double_value_ || has_int32_value_) return false; |
3572 ASSERT(!handle_.is_null()); | 3548 ASSERT(!handle_.is_null()); |
3573 return type_from_value_.IsString(); | 3549 return type_.IsString(); |
3574 } | 3550 } |
3575 Handle<String> StringValue() const { | 3551 Handle<String> StringValue() const { |
3576 ASSERT(HasStringValue()); | 3552 ASSERT(HasStringValue()); |
3577 return Handle<String>::cast(handle_); | 3553 return Handle<String>::cast(handle_); |
3578 } | 3554 } |
3579 bool HasInternalizedStringValue() const { | 3555 bool HasInternalizedStringValue() const { |
3580 return HasStringValue() && is_internalized_string_; | 3556 return HasStringValue() && is_internalized_string_; |
3581 } | 3557 } |
3582 | 3558 |
3583 bool BooleanValue() const { return boolean_value_; } | 3559 bool BooleanValue() const { return boolean_value_; } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3648 // not the converse. | 3624 // not the converse. |
3649 bool has_smi_value_ : 1; | 3625 bool has_smi_value_ : 1; |
3650 bool has_int32_value_ : 1; | 3626 bool has_int32_value_ : 1; |
3651 bool has_double_value_ : 1; | 3627 bool has_double_value_ : 1; |
3652 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. | 3628 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
3653 bool is_not_in_new_space_ : 1; | 3629 bool is_not_in_new_space_ : 1; |
3654 bool is_cell_ : 1; | 3630 bool is_cell_ : 1; |
3655 bool boolean_value_ : 1; | 3631 bool boolean_value_ : 1; |
3656 int32_t int32_value_; | 3632 int32_t int32_value_; |
3657 double double_value_; | 3633 double double_value_; |
3658 HType type_from_value_; | |
3659 }; | 3634 }; |
3660 | 3635 |
3661 | 3636 |
3662 class HBinaryOperation: public HTemplateInstruction<3> { | 3637 class HBinaryOperation: public HTemplateInstruction<3> { |
3663 public: | 3638 public: |
3664 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3639 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
3665 : observed_output_representation_(Representation::None()) { | 3640 : observed_output_representation_(Representation::None()) { |
3666 ASSERT(left != NULL && right != NULL); | 3641 ASSERT(left != NULL && right != NULL); |
3667 SetOperandAt(0, context); | 3642 SetOperandAt(0, context); |
3668 SetOperandAt(1, left); | 3643 SetOperandAt(1, left); |
(...skipping 3204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6873 virtual bool IsDeletable() const { return true; } | 6848 virtual bool IsDeletable() const { return true; } |
6874 }; | 6849 }; |
6875 | 6850 |
6876 | 6851 |
6877 #undef DECLARE_INSTRUCTION | 6852 #undef DECLARE_INSTRUCTION |
6878 #undef DECLARE_CONCRETE_INSTRUCTION | 6853 #undef DECLARE_CONCRETE_INSTRUCTION |
6879 | 6854 |
6880 } } // namespace v8::internal | 6855 } } // namespace v8::internal |
6881 | 6856 |
6882 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6857 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |