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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 } | 387 } |
388 | 388 |
389 bool Equals(const HType& other) { | 389 bool Equals(const HType& other) { |
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() { |
Jakob Kummerow
2013/03/13 15:50:31
forgot to mark this const too?
Yang
2013/03/13 17:00:15
Done.
| |
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() { return boolean_value_; } |
Jakob Kummerow
2013/03/13 15:50:31
nit: boolean_value()
Yang
2013/03/13 17:00:15
I thought camel case was more appropriate since St
| |
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 27 matching lines...) Expand all Loading... | |
3214 // HeapObject the constant originated from or is null. If the | 3233 // HeapObject the constant originated from or is null. If the |
3215 // constant is non-numeric, handle_ always points to a valid | 3234 // constant is non-numeric, handle_ always points to a valid |
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; |
Jakob Kummerow
2013/03/13 15:50:31
I would be nice to replace this with type_from_val
Yang
2013/03/13 17:00:15
Done.
| |
3225 bool has_double_value_ : 1; | 3244 bool has_double_value_ : 1; |
3226 int32_t int32_value_; | 3245 int32_t int32_value_; |
3227 double double_value_; | 3246 double double_value_; |
3247 HType type_from_value_; | |
3248 bool is_internalized_string_; // TODO(yangguo) make this part of HType | |
Jakob Kummerow
2013/03/13 15:50:31
Please move this up to the other has_$FOO_value_ p
Yang
2013/03/13 17:00:15
Done.
| |
3249 bool boolean_value_; | |
Jakob Kummerow
2013/03/13 15:50:31
Please move this up to the other $FOO_value_ prope
Yang
2013/03/13 17:00:15
Done.
| |
3250 intptr_t handle_hash_; | |
3228 }; | 3251 }; |
3229 | 3252 |
3230 | 3253 |
3231 class HBinaryOperation: public HTemplateInstruction<3> { | 3254 class HBinaryOperation: public HTemplateInstruction<3> { |
3232 public: | 3255 public: |
3233 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3256 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
3234 : observed_output_representation_(Representation::None()) { | 3257 : observed_output_representation_(Representation::None()) { |
3235 ASSERT(left != NULL && right != NULL); | 3258 ASSERT(left != NULL && right != NULL); |
3236 SetOperandAt(0, context); | 3259 SetOperandAt(0, context); |
3237 SetOperandAt(1, left); | 3260 SetOperandAt(1, left); |
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4519 } | 4542 } |
4520 | 4543 |
4521 Handle<JSGlobalPropertyCell> cell() const { return cell_; } | 4544 Handle<JSGlobalPropertyCell> cell() const { return cell_; } |
4522 bool RequiresHoleCheck() const; | 4545 bool RequiresHoleCheck() const; |
4523 | 4546 |
4524 virtual void PrintDataTo(StringStream* stream); | 4547 virtual void PrintDataTo(StringStream* stream); |
4525 | 4548 |
4526 virtual intptr_t Hashcode() { | 4549 virtual intptr_t Hashcode() { |
4527 ASSERT_ALLOCATION_DISABLED; | 4550 ASSERT_ALLOCATION_DISABLED; |
4528 // Dereferencing to use the object's raw address for hashing is safe. | 4551 // Dereferencing to use the object's raw address for hashing is safe. |
4529 AllowHandleDereference allow_handle_deref(isolate()); | 4552 HandleDereferenceGuard allow_handle_deref(isolate(), |
4553 HandleDereferenceGuard::ALLOW); | |
4554 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || | |
4555 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); | |
4530 return reinterpret_cast<intptr_t>(*cell_); | 4556 return reinterpret_cast<intptr_t>(*cell_); |
4531 } | 4557 } |
4532 | 4558 |
4533 virtual Representation RequiredInputRepresentation(int index) { | 4559 virtual Representation RequiredInputRepresentation(int index) { |
4534 return Representation::None(); | 4560 return Representation::None(); |
4535 } | 4561 } |
4536 | 4562 |
4537 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) | 4563 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) |
4538 | 4564 |
4539 protected: | 4565 protected: |
(...skipping 1658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6198 virtual bool IsDeletable() const { return true; } | 6224 virtual bool IsDeletable() const { return true; } |
6199 }; | 6225 }; |
6200 | 6226 |
6201 | 6227 |
6202 #undef DECLARE_INSTRUCTION | 6228 #undef DECLARE_INSTRUCTION |
6203 #undef DECLARE_CONCRETE_INSTRUCTION | 6229 #undef DECLARE_CONCRETE_INSTRUCTION |
6204 | 6230 |
6205 } } // namespace v8::internal | 6231 } } // namespace v8::internal |
6206 | 6232 |
6207 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6233 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |