| 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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 static HType NonPrimitive() { return HType(kNonPrimitive); } | 379 static HType NonPrimitive() { return HType(kNonPrimitive); } |
| 380 static HType JSArray() { return HType(kJSArray); } | 380 static HType JSArray() { return HType(kJSArray); } |
| 381 static HType JSObject() { return HType(kJSObject); } | 381 static HType JSObject() { return HType(kJSObject); } |
| 382 static HType Uninitialized() { return HType(kUninitialized); } | 382 static HType Uninitialized() { return HType(kUninitialized); } |
| 383 | 383 |
| 384 // Return the weakest (least precise) common type. | 384 // Return the weakest (least precise) common type. |
| 385 HType Combine(HType other) { | 385 HType Combine(HType other) { |
| 386 return HType(static_cast<Type>(type_ & other.type_)); | 386 return HType(static_cast<Type>(type_ & other.type_)); |
| 387 } | 387 } |
| 388 | 388 |
| 389 bool Equals(const HType& other) { | 389 bool Equals(const HType& other) const { |
| 390 return type_ == other.type_; | 390 return type_ == other.type_; |
| 391 } | 391 } |
| 392 | 392 |
| 393 bool IsSubtypeOf(const HType& other) { | 393 bool IsSubtypeOf(const HType& other) { |
| 394 return Combine(other).Equals(other); | 394 return Combine(other).Equals(other); |
| 395 } | 395 } |
| 396 | 396 |
| 397 bool IsTagged() { | 397 bool IsTagged() const { |
| 398 ASSERT(type_ != kUninitialized); | 398 ASSERT(type_ != kUninitialized); |
| 399 return ((type_ & kTagged) == kTagged); | 399 return ((type_ & kTagged) == kTagged); |
| 400 } | 400 } |
| 401 | 401 |
| 402 bool IsTaggedPrimitive() { | 402 bool IsTaggedPrimitive() const { |
| 403 ASSERT(type_ != kUninitialized); | 403 ASSERT(type_ != kUninitialized); |
| 404 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); | 404 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); |
| 405 } | 405 } |
| 406 | 406 |
| 407 bool IsTaggedNumber() { | 407 bool IsTaggedNumber() const { |
| 408 ASSERT(type_ != kUninitialized); | 408 ASSERT(type_ != kUninitialized); |
| 409 return ((type_ & kTaggedNumber) == kTaggedNumber); | 409 return ((type_ & kTaggedNumber) == kTaggedNumber); |
| 410 } | 410 } |
| 411 | 411 |
| 412 bool IsSmi() { | 412 bool IsSmi() const { |
| 413 ASSERT(type_ != kUninitialized); | 413 ASSERT(type_ != kUninitialized); |
| 414 return ((type_ & kSmi) == kSmi); | 414 return ((type_ & kSmi) == kSmi); |
| 415 } | 415 } |
| 416 | 416 |
| 417 bool IsHeapNumber() { | 417 bool IsHeapNumber() const { |
| 418 ASSERT(type_ != kUninitialized); | 418 ASSERT(type_ != kUninitialized); |
| 419 return ((type_ & kHeapNumber) == kHeapNumber); | 419 return ((type_ & kHeapNumber) == kHeapNumber); |
| 420 } | 420 } |
| 421 | 421 |
| 422 bool IsString() { | 422 bool IsString() const { |
| 423 ASSERT(type_ != kUninitialized); | 423 ASSERT(type_ != kUninitialized); |
| 424 return ((type_ & kString) == kString); | 424 return ((type_ & kString) == kString); |
| 425 } | 425 } |
| 426 | 426 |
| 427 bool IsBoolean() { | 427 bool IsBoolean() const { |
| 428 ASSERT(type_ != kUninitialized); | 428 ASSERT(type_ != kUninitialized); |
| 429 return ((type_ & kBoolean) == kBoolean); | 429 return ((type_ & kBoolean) == kBoolean); |
| 430 } | 430 } |
| 431 | 431 |
| 432 bool IsNonPrimitive() { | 432 bool IsNonPrimitive() const { |
| 433 ASSERT(type_ != kUninitialized); | 433 ASSERT(type_ != kUninitialized); |
| 434 return ((type_ & kNonPrimitive) == kNonPrimitive); | 434 return ((type_ & kNonPrimitive) == kNonPrimitive); |
| 435 } | 435 } |
| 436 | 436 |
| 437 bool IsJSArray() { | 437 bool IsJSArray() const { |
| 438 ASSERT(type_ != kUninitialized); | 438 ASSERT(type_ != kUninitialized); |
| 439 return ((type_ & kJSArray) == kJSArray); | 439 return ((type_ & kJSArray) == kJSArray); |
| 440 } | 440 } |
| 441 | 441 |
| 442 bool IsJSObject() { | 442 bool IsJSObject() const { |
| 443 ASSERT(type_ != kUninitialized); | 443 ASSERT(type_ != kUninitialized); |
| 444 return ((type_ & kJSObject) == kJSObject); | 444 return ((type_ & kJSObject) == kJSObject); |
| 445 } | 445 } |
| 446 | 446 |
| 447 bool IsUninitialized() { | 447 bool IsUninitialized() const { |
| 448 return type_ == kUninitialized; | 448 return type_ == kUninitialized; |
| 449 } | 449 } |
| 450 | 450 |
| 451 bool IsHeapObject() { | 451 bool IsHeapObject() const { |
| 452 ASSERT(type_ != kUninitialized); | 452 ASSERT(type_ != kUninitialized); |
| 453 return IsHeapNumber() || IsString() || IsNonPrimitive(); | 453 return IsHeapNumber() || IsString() || IsNonPrimitive(); |
| 454 } | 454 } |
| 455 | 455 |
| 456 static HType TypeFromValue(Isolate* isolate, Handle<Object> value); | 456 static HType TypeFromValue(Handle<Object> value); |
| 457 | 457 |
| 458 const char* ToString(); | 458 const char* ToString(); |
| 459 | 459 |
| 460 private: | 460 private: |
| 461 enum Type { | 461 enum Type { |
| 462 kTagged = 0x1, // 0000 0000 0000 0001 | 462 kTagged = 0x1, // 0000 0000 0000 0001 |
| 463 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | 463 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 |
| 464 kTaggedNumber = 0xd, // 0000 0000 0000 1101 | 464 kTaggedNumber = 0xd, // 0000 0000 0000 1101 |
| 465 kSmi = 0x1d, // 0000 0000 0001 1101 | 465 kSmi = 0x1d, // 0000 0000 0001 1101 |
| 466 kHeapNumber = 0x2d, // 0000 0000 0010 1101 | 466 kHeapNumber = 0x2d, // 0000 0000 0010 1101 |
| (...skipping 2318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2785 | 2785 |
| 2786 virtual Representation RequiredInputRepresentation(int index) { | 2786 virtual Representation RequiredInputRepresentation(int index) { |
| 2787 return Representation::None(); | 2787 return Representation::None(); |
| 2788 } | 2788 } |
| 2789 | 2789 |
| 2790 virtual void PrintDataTo(StringStream* stream); | 2790 virtual void PrintDataTo(StringStream* stream); |
| 2791 | 2791 |
| 2792 virtual intptr_t Hashcode() { | 2792 virtual intptr_t Hashcode() { |
| 2793 ASSERT_ALLOCATION_DISABLED; | 2793 ASSERT_ALLOCATION_DISABLED; |
| 2794 // Dereferencing to use the object's raw address for hashing is safe. | 2794 // Dereferencing to use the object's raw address for hashing is safe. |
| 2795 AllowHandleDereference allow_handle_deref(isolate()); | 2795 HandleDereferenceGuard allow_handle_deref(isolate(), |
| 2796 HandleDereferenceGuard::ALLOW); |
| 2797 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || |
| 2798 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); |
| 2796 intptr_t hash = 0; | 2799 intptr_t hash = 0; |
| 2797 for (int i = 0; i < prototypes_.length(); i++) { | 2800 for (int i = 0; i < prototypes_.length(); i++) { |
| 2798 hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]); | 2801 hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]); |
| 2799 hash = 17 * hash + reinterpret_cast<intptr_t>(*maps_[i]); | 2802 hash = 17 * hash + reinterpret_cast<intptr_t>(*maps_[i]); |
| 2800 } | 2803 } |
| 2801 return hash; | 2804 return hash; |
| 2802 } | 2805 } |
| 2803 | 2806 |
| 2804 bool CanOmitPrototypeChecks() { | 2807 bool CanOmitPrototypeChecks() { |
| 2805 for (int i = 0; i < maps()->length(); i++) { | 2808 for (int i = 0; i < maps()->length(); i++) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3063 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) | 3066 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) |
| 3064 | 3067 |
| 3065 private: | 3068 private: |
| 3066 virtual bool IsDeletable() const { return true; } | 3069 virtual bool IsDeletable() const { return true; } |
| 3067 }; | 3070 }; |
| 3068 | 3071 |
| 3069 | 3072 |
| 3070 class HConstant: public HTemplateInstruction<0> { | 3073 class HConstant: public HTemplateInstruction<0> { |
| 3071 public: | 3074 public: |
| 3072 HConstant(Handle<Object> handle, Representation r); | 3075 HConstant(Handle<Object> handle, Representation r); |
| 3073 HConstant(int32_t value, Representation r); | 3076 HConstant(int32_t value, |
| 3074 HConstant(double value, Representation r); | 3077 Representation r, |
| 3078 Handle<Object> optional_handle = Handle<Object>::null()); |
| 3079 HConstant(double value, |
| 3080 Representation r, |
| 3081 Handle<Object> optional_handle = Handle<Object>::null()); |
| 3082 HConstant(Handle<Object> handle, |
| 3083 Representation r, |
| 3084 HType type, |
| 3085 bool is_internalized_string, |
| 3086 bool boolean_value); |
| 3075 | 3087 |
| 3076 Handle<Object> handle() { | 3088 Handle<Object> handle() { |
| 3077 if (handle_.is_null()) { | 3089 if (handle_.is_null()) { |
| 3078 handle_ = FACTORY->NewNumber(double_value_, TENURED); | 3090 handle_ = FACTORY->NewNumber(double_value_, TENURED); |
| 3079 } | 3091 } |
| 3080 ASSERT(has_int32_value_ || !handle_->IsSmi()); | 3092 ASSERT(has_int32_value_ || !handle_->IsSmi()); |
| 3081 return handle_; | 3093 return handle_; |
| 3082 } | 3094 } |
| 3083 | 3095 |
| 3084 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } | 3096 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } |
| 3085 | 3097 |
| 3086 bool ImmortalImmovable() const { | 3098 bool ImmortalImmovable() const { |
| 3087 if (has_int32_value_) { | 3099 if (has_int32_value_) { |
| 3088 return false; | 3100 return false; |
| 3089 } | 3101 } |
| 3090 if (has_double_value_) { | 3102 if (has_double_value_) { |
| 3091 if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || | 3103 if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || |
| 3092 isnan(double_value_)) { | 3104 isnan(double_value_)) { |
| 3093 return true; | 3105 return true; |
| 3094 } | 3106 } |
| 3095 return false; | 3107 return false; |
| 3096 } | 3108 } |
| 3097 | 3109 |
| 3098 ASSERT(!handle_.is_null()); | 3110 ASSERT(!handle_.is_null()); |
| 3099 Heap* heap = isolate()->heap(); | 3111 Heap* heap = isolate()->heap(); |
| 3100 // We should have handled minus_zero_value and nan_value in the | 3112 // We should have handled minus_zero_value and nan_value in the |
| 3101 // has_double_value_ clause above. | 3113 // has_double_value_ clause above. |
| 3102 // Dereferencing is safe to compare against singletons. | 3114 // Dereferencing is safe to compare against immovable singletons. |
| 3103 AllowHandleDereference allow_handle_deref(isolate()); | 3115 HandleDereferenceGuard allow_handle_deref(isolate(), |
| 3116 HandleDereferenceGuard::ALLOW); |
| 3104 ASSERT(*handle_ != heap->minus_zero_value()); | 3117 ASSERT(*handle_ != heap->minus_zero_value()); |
| 3105 ASSERT(*handle_ != heap->nan_value()); | 3118 ASSERT(*handle_ != heap->nan_value()); |
| 3106 return *handle_ == heap->undefined_value() || | 3119 return *handle_ == heap->undefined_value() || |
| 3107 *handle_ == heap->null_value() || | 3120 *handle_ == heap->null_value() || |
| 3108 *handle_ == heap->true_value() || | 3121 *handle_ == heap->true_value() || |
| 3109 *handle_ == heap->false_value() || | 3122 *handle_ == heap->false_value() || |
| 3110 *handle_ == heap->the_hole_value() || | 3123 *handle_ == heap->the_hole_value() || |
| 3111 *handle_ == heap->empty_string(); | 3124 *handle_ == heap->empty_string(); |
| 3112 } | 3125 } |
| 3113 | 3126 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3142 int32_t NumberValueAsInteger32() const { | 3155 int32_t NumberValueAsInteger32() const { |
| 3143 ASSERT(HasNumberValue()); | 3156 ASSERT(HasNumberValue()); |
| 3144 // Irrespective of whether a numeric HConstant can be safely | 3157 // Irrespective of whether a numeric HConstant can be safely |
| 3145 // represented as an int32, we store the (in some cases lossy) | 3158 // represented as an int32, we store the (in some cases lossy) |
| 3146 // representation of the number in int32_value_. | 3159 // representation of the number in int32_value_. |
| 3147 return int32_value_; | 3160 return int32_value_; |
| 3148 } | 3161 } |
| 3149 bool HasStringValue() const { | 3162 bool HasStringValue() const { |
| 3150 if (has_double_value_ || has_int32_value_) return false; | 3163 if (has_double_value_ || has_int32_value_) return false; |
| 3151 ASSERT(!handle_.is_null()); | 3164 ASSERT(!handle_.is_null()); |
| 3152 return handle_->IsString(); | 3165 return type_from_value_.IsString(); |
| 3153 } | 3166 } |
| 3154 Handle<String> StringValue() const { | 3167 Handle<String> StringValue() const { |
| 3155 ASSERT(HasStringValue()); | 3168 ASSERT(HasStringValue()); |
| 3156 return Handle<String>::cast(handle_); | 3169 return Handle<String>::cast(handle_); |
| 3157 } | 3170 } |
| 3171 bool HasInternalizedStringValue() const { |
| 3172 return HasStringValue() && is_internalized_string_; |
| 3173 } |
| 3158 | 3174 |
| 3159 bool ToBoolean(); | 3175 bool BooleanValue() const { return boolean_value_; } |
| 3160 | 3176 |
| 3161 bool IsUint32() { | 3177 bool IsUint32() { |
| 3162 return HasInteger32Value() && (Integer32Value() >= 0); | 3178 return HasInteger32Value() && (Integer32Value() >= 0); |
| 3163 } | 3179 } |
| 3164 | 3180 |
| 3165 virtual intptr_t Hashcode() { | 3181 virtual intptr_t Hashcode() { |
| 3166 ASSERT_ALLOCATION_DISABLED; | 3182 ASSERT_ALLOCATION_DISABLED; |
| 3167 intptr_t hash; | 3183 intptr_t hash; |
| 3168 | 3184 |
| 3169 if (has_int32_value_) { | 3185 if (has_int32_value_) { |
| 3170 hash = static_cast<intptr_t>(int32_value_); | 3186 hash = static_cast<intptr_t>(int32_value_); |
| 3171 } else if (has_double_value_) { | 3187 } else if (has_double_value_) { |
| 3172 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3188 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
| 3173 } else { | 3189 } else { |
| 3174 ASSERT(!handle_.is_null()); | 3190 ASSERT(!handle_.is_null()); |
| 3175 // Dereferencing to use the object's raw address for hashing is safe. | 3191 // Dereferencing to use the object's raw address for hashing is safe. |
| 3176 AllowHandleDereference allow_handle_deref(isolate()); | 3192 HandleDereferenceGuard allow_handle_deref(isolate(), |
| 3193 HandleDereferenceGuard::ALLOW); |
| 3194 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || |
| 3195 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); |
| 3177 hash = reinterpret_cast<intptr_t>(*handle_); | 3196 hash = reinterpret_cast<intptr_t>(*handle_); |
| 3178 } | 3197 } |
| 3179 | 3198 |
| 3180 return hash; | 3199 return hash; |
| 3181 } | 3200 } |
| 3182 | 3201 |
| 3183 #ifdef DEBUG | 3202 #ifdef DEBUG |
| 3184 virtual void Verify() { } | 3203 virtual void Verify() { } |
| 3185 #endif | 3204 #endif |
| 3186 | 3205 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3216 // constant HeapObject. | 3235 // constant HeapObject. |
| 3217 Handle<Object> handle_; | 3236 Handle<Object> handle_; |
| 3218 | 3237 |
| 3219 // We store the HConstant in the most specific form safely possible. | 3238 // We store the HConstant in the most specific form safely possible. |
| 3220 // The two flags, has_int32_value_ and has_double_value_ tell us if | 3239 // The two flags, has_int32_value_ and has_double_value_ tell us if |
| 3221 // int32_value_ and double_value_ hold valid, safe representations | 3240 // int32_value_ and double_value_ hold valid, safe representations |
| 3222 // of the constant. has_int32_value_ implies has_double_value_ but | 3241 // of the constant. has_int32_value_ implies has_double_value_ but |
| 3223 // not the converse. | 3242 // not the converse. |
| 3224 bool has_int32_value_ : 1; | 3243 bool has_int32_value_ : 1; |
| 3225 bool has_double_value_ : 1; | 3244 bool has_double_value_ : 1; |
| 3245 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
| 3246 bool boolean_value_ : 1; |
| 3226 int32_t int32_value_; | 3247 int32_t int32_value_; |
| 3227 double double_value_; | 3248 double double_value_; |
| 3249 HType type_from_value_; |
| 3228 }; | 3250 }; |
| 3229 | 3251 |
| 3230 | 3252 |
| 3231 class HBinaryOperation: public HTemplateInstruction<3> { | 3253 class HBinaryOperation: public HTemplateInstruction<3> { |
| 3232 public: | 3254 public: |
| 3233 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3255 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
| 3234 : observed_output_representation_(Representation::None()) { | 3256 : observed_output_representation_(Representation::None()) { |
| 3235 ASSERT(left != NULL && right != NULL); | 3257 ASSERT(left != NULL && right != NULL); |
| 3236 SetOperandAt(0, context); | 3258 SetOperandAt(0, context); |
| 3237 SetOperandAt(1, left); | 3259 SetOperandAt(1, left); |
| (...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4519 } | 4541 } |
| 4520 | 4542 |
| 4521 Handle<JSGlobalPropertyCell> cell() const { return cell_; } | 4543 Handle<JSGlobalPropertyCell> cell() const { return cell_; } |
| 4522 bool RequiresHoleCheck() const; | 4544 bool RequiresHoleCheck() const; |
| 4523 | 4545 |
| 4524 virtual void PrintDataTo(StringStream* stream); | 4546 virtual void PrintDataTo(StringStream* stream); |
| 4525 | 4547 |
| 4526 virtual intptr_t Hashcode() { | 4548 virtual intptr_t Hashcode() { |
| 4527 ASSERT_ALLOCATION_DISABLED; | 4549 ASSERT_ALLOCATION_DISABLED; |
| 4528 // Dereferencing to use the object's raw address for hashing is safe. | 4550 // Dereferencing to use the object's raw address for hashing is safe. |
| 4529 AllowHandleDereference allow_handle_deref(isolate()); | 4551 HandleDereferenceGuard allow_handle_deref(isolate(), |
| 4552 HandleDereferenceGuard::ALLOW); |
| 4553 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || |
| 4554 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); |
| 4530 return reinterpret_cast<intptr_t>(*cell_); | 4555 return reinterpret_cast<intptr_t>(*cell_); |
| 4531 } | 4556 } |
| 4532 | 4557 |
| 4533 virtual Representation RequiredInputRepresentation(int index) { | 4558 virtual Representation RequiredInputRepresentation(int index) { |
| 4534 return Representation::None(); | 4559 return Representation::None(); |
| 4535 } | 4560 } |
| 4536 | 4561 |
| 4537 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) | 4562 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) |
| 4538 | 4563 |
| 4539 protected: | 4564 protected: |
| (...skipping 1658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6198 virtual bool IsDeletable() const { return true; } | 6223 virtual bool IsDeletable() const { return true; } |
| 6199 }; | 6224 }; |
| 6200 | 6225 |
| 6201 | 6226 |
| 6202 #undef DECLARE_INSTRUCTION | 6227 #undef DECLARE_INSTRUCTION |
| 6203 #undef DECLARE_CONCRETE_INSTRUCTION | 6228 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6204 | 6229 |
| 6205 } } // namespace v8::internal | 6230 } } // namespace v8::internal |
| 6206 | 6231 |
| 6207 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6232 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |