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 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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) { } | 353 HType() : type_(kUninitialized) { } |
354 | 354 |
355 static HType None() { return HType(kNone); } | |
355 static HType Tagged() { return HType(kTagged); } | 356 static HType Tagged() { return HType(kTagged); } |
356 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } | 357 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } |
357 static HType TaggedNumber() { return HType(kTaggedNumber); } | 358 static HType TaggedNumber() { return HType(kTaggedNumber); } |
358 static HType Smi() { return HType(kSmi); } | 359 static HType Smi() { return HType(kSmi); } |
359 static HType HeapNumber() { return HType(kHeapNumber); } | 360 static HType HeapNumber() { return HType(kHeapNumber); } |
360 static HType String() { return HType(kString); } | 361 static HType String() { return HType(kString); } |
361 static HType Boolean() { return HType(kBoolean); } | 362 static HType Boolean() { return HType(kBoolean); } |
362 static HType NonPrimitive() { return HType(kNonPrimitive); } | 363 static HType NonPrimitive() { return HType(kNonPrimitive); } |
363 static HType JSArray() { return HType(kJSArray); } | 364 static HType JSArray() { return HType(kJSArray); } |
364 static HType JSObject() { return HType(kJSObject); } | 365 static HType JSObject() { return HType(kJSObject); } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 ASSERT(type_ != kUninitialized); | 436 ASSERT(type_ != kUninitialized); |
436 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); | 437 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); |
437 } | 438 } |
438 | 439 |
439 static HType TypeFromValue(Handle<Object> value); | 440 static HType TypeFromValue(Handle<Object> value); |
440 | 441 |
441 const char* ToString(); | 442 const char* ToString(); |
442 | 443 |
443 private: | 444 private: |
444 enum Type { | 445 enum Type { |
446 kNone = 0x0, // 0000 0000 0000 0000 | |
445 kTagged = 0x1, // 0000 0000 0000 0001 | 447 kTagged = 0x1, // 0000 0000 0000 0001 |
446 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | 448 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 |
447 kTaggedNumber = 0xd, // 0000 0000 0000 1101 | 449 kTaggedNumber = 0xd, // 0000 0000 0000 1101 |
448 kSmi = 0x1d, // 0000 0000 0001 1101 | 450 kSmi = 0x1d, // 0000 0000 0001 1101 |
449 kHeapNumber = 0x2d, // 0000 0000 0010 1101 | 451 kHeapNumber = 0x2d, // 0000 0000 0010 1101 |
450 kString = 0x45, // 0000 0000 0100 0101 | 452 kString = 0x45, // 0000 0000 0100 0101 |
451 kBoolean = 0x85, // 0000 0000 1000 0101 | 453 kBoolean = 0x85, // 0000 0000 1000 0101 |
452 kNonPrimitive = 0x101, // 0000 0001 0000 0001 | 454 kNonPrimitive = 0x101, // 0000 0001 0000 0001 |
453 kJSObject = 0x301, // 0000 0011 0000 0001 | 455 kJSObject = 0x301, // 0000 0011 0000 0001 |
454 kJSArray = 0x701, // 0000 0111 0000 0001 | 456 kJSArray = 0x701, // 0000 0111 0000 0001 |
(...skipping 2821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3276 bool is_not_in_new_space = true, | 3278 bool is_not_in_new_space = true, |
3277 Handle<Object> optional_handle = Handle<Object>::null()); | 3279 Handle<Object> optional_handle = Handle<Object>::null()); |
3278 HConstant(Handle<Object> handle, | 3280 HConstant(Handle<Object> handle, |
3279 UniqueValueId unique_id, | 3281 UniqueValueId unique_id, |
3280 Representation r, | 3282 Representation r, |
3281 HType type, | 3283 HType type, |
3282 bool is_internalized_string, | 3284 bool is_internalized_string, |
3283 bool is_not_in_new_space, | 3285 bool is_not_in_new_space, |
3284 bool is_cell, | 3286 bool is_cell, |
3285 bool boolean_value); | 3287 bool boolean_value); |
3288 HConstant(ExternalReference reference, | |
3289 Representation r = Representation::None()); | |
danno
2013/07/22 14:19:55
Why None? It seems to make much more sense to use
Benedikt Meurer
2013/07/23 07:00:48
Copy'n'paste....
| |
3286 | 3290 |
3287 Handle<Object> handle() { | 3291 Handle<Object> handle() { |
3288 if (handle_.is_null()) { | 3292 if (handle_.is_null()) { |
3289 Factory* factory = Isolate::Current()->factory(); | 3293 Factory* factory = Isolate::Current()->factory(); |
3290 // Default arguments to is_not_in_new_space depend on this heap number | 3294 // Default arguments to is_not_in_new_space depend on this heap number |
3291 // to be tenured so that it's guaranteed not be be located in new space. | 3295 // to be tenured so that it's guaranteed not be be located in new space. |
3292 handle_ = factory->NewNumber(double_value_, TENURED); | 3296 handle_ = factory->NewNumber(double_value_, TENURED); |
3293 } | 3297 } |
3294 AllowDeferredHandleDereference smi_check; | 3298 AllowDeferredHandleDereference smi_check; |
3295 ASSERT(has_int32_value_ || !handle_->IsSmi()); | 3299 ASSERT(has_int32_value_ || !handle_->IsSmi()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3335 } | 3339 } |
3336 | 3340 |
3337 virtual Representation RequiredInputRepresentation(int index) { | 3341 virtual Representation RequiredInputRepresentation(int index) { |
3338 return Representation::None(); | 3342 return Representation::None(); |
3339 } | 3343 } |
3340 | 3344 |
3341 virtual Representation KnownOptimalRepresentation() { | 3345 virtual Representation KnownOptimalRepresentation() { |
3342 if (HasSmiValue()) return Representation::Smi(); | 3346 if (HasSmiValue()) return Representation::Smi(); |
3343 if (HasInteger32Value()) return Representation::Integer32(); | 3347 if (HasInteger32Value()) return Representation::Integer32(); |
3344 if (HasNumberValue()) return Representation::Double(); | 3348 if (HasNumberValue()) return Representation::Double(); |
3349 if (HasExternalValue()) return Representation::External(); | |
3345 return Representation::Tagged(); | 3350 return Representation::Tagged(); |
3346 } | 3351 } |
3347 | 3352 |
3348 virtual bool EmitAtUses(); | 3353 virtual bool EmitAtUses(); |
3349 virtual void PrintDataTo(StringStream* stream); | 3354 virtual void PrintDataTo(StringStream* stream); |
3350 virtual HType CalculateInferredType(); | 3355 virtual HType CalculateInferredType(); |
3351 bool IsInteger() { return handle()->IsSmi(); } | 3356 bool IsInteger() { return handle()->IsSmi(); } |
3352 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; | 3357 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
3353 HConstant* CopyToTruncatedInt32(Zone* zone) const; | 3358 HConstant* CopyToTruncatedInt32(Zone* zone) const; |
3354 bool HasInteger32Value() const { return has_int32_value_; } | 3359 bool HasInteger32Value() const { return has_int32_value_; } |
(...skipping 30 matching lines...) Expand all Loading... | |
3385 ASSERT(!handle_.is_null()); | 3390 ASSERT(!handle_.is_null()); |
3386 return type_from_value_.IsString(); | 3391 return type_from_value_.IsString(); |
3387 } | 3392 } |
3388 Handle<String> StringValue() const { | 3393 Handle<String> StringValue() const { |
3389 ASSERT(HasStringValue()); | 3394 ASSERT(HasStringValue()); |
3390 return Handle<String>::cast(handle_); | 3395 return Handle<String>::cast(handle_); |
3391 } | 3396 } |
3392 bool HasInternalizedStringValue() const { | 3397 bool HasInternalizedStringValue() const { |
3393 return HasStringValue() && is_internalized_string_; | 3398 return HasStringValue() && is_internalized_string_; |
3394 } | 3399 } |
3400 bool HasExternalValue() const { return has_external_value_; } | |
3401 ExternalReference ExternalValue() const { return external_value_; } | |
3395 | 3402 |
3396 bool BooleanValue() const { return boolean_value_; } | 3403 bool BooleanValue() const { return boolean_value_; } |
3397 | 3404 |
3398 virtual intptr_t Hashcode() { | 3405 virtual intptr_t Hashcode() { |
3399 if (has_int32_value_) { | 3406 if (has_int32_value_) { |
3400 return static_cast<intptr_t>(int32_value_); | 3407 return static_cast<intptr_t>(int32_value_); |
3401 } else if (has_double_value_) { | 3408 } else if (has_double_value_) { |
3402 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3409 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
3410 } else if (has_external_value_) { | |
3411 return reinterpret_cast<intptr_t>(external_value_.address()); | |
3403 } else { | 3412 } else { |
3404 ASSERT(!handle_.is_null()); | 3413 ASSERT(!handle_.is_null()); |
3405 return unique_id_.Hashcode(); | 3414 return unique_id_.Hashcode(); |
3406 } | 3415 } |
3407 } | 3416 } |
3408 | 3417 |
3409 virtual void FinalizeUniqueValueId() { | 3418 virtual void FinalizeUniqueValueId() { |
3410 if (!has_double_value_) { | 3419 if (!has_double_value_ && !has_external_value_) { |
3411 ASSERT(!handle_.is_null()); | 3420 ASSERT(!handle_.is_null()); |
3412 unique_id_ = UniqueValueId(handle_); | 3421 unique_id_ = UniqueValueId(handle_); |
3413 } | 3422 } |
3414 } | 3423 } |
3415 | 3424 |
3416 bool UniqueValueIdsMatch(UniqueValueId other) { | 3425 bool UniqueValueIdsMatch(UniqueValueId other) { |
3417 return !has_double_value_ && unique_id_ == other; | 3426 return !has_double_value_ && !has_external_value_ && unique_id_ == other; |
3418 } | 3427 } |
3419 | 3428 |
3420 #ifdef DEBUG | 3429 #ifdef DEBUG |
3421 virtual void Verify() { } | 3430 virtual void Verify() { } |
3422 #endif | 3431 #endif |
3423 | 3432 |
3424 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3433 DECLARE_CONCRETE_INSTRUCTION(Constant) |
3425 | 3434 |
3426 protected: | 3435 protected: |
3427 virtual Range* InferRange(Zone* zone); | 3436 virtual Range* InferRange(Zone* zone); |
3428 | 3437 |
3429 virtual bool DataEquals(HValue* other) { | 3438 virtual bool DataEquals(HValue* other) { |
3430 HConstant* other_constant = HConstant::cast(other); | 3439 HConstant* other_constant = HConstant::cast(other); |
3431 if (has_int32_value_) { | 3440 if (has_int32_value_) { |
3432 return other_constant->has_int32_value_ && | 3441 return other_constant->has_int32_value_ && |
3433 int32_value_ == other_constant->int32_value_; | 3442 int32_value_ == other_constant->int32_value_; |
3434 } else if (has_double_value_) { | 3443 } else if (has_double_value_) { |
3435 return other_constant->has_double_value_ && | 3444 return other_constant->has_double_value_ && |
3436 BitCast<int64_t>(double_value_) == | 3445 BitCast<int64_t>(double_value_) == |
3437 BitCast<int64_t>(other_constant->double_value_); | 3446 BitCast<int64_t>(other_constant->double_value_); |
3447 } else if (has_external_value_) { | |
3448 return other_constant->has_external_value_ && | |
3449 external_value_ == other_constant->external_value_; | |
3438 } else { | 3450 } else { |
3439 ASSERT(!handle_.is_null()); | 3451 ASSERT(!handle_.is_null()); |
3440 return !other_constant->handle_.is_null() && | 3452 return !other_constant->handle_.is_null() && |
3441 unique_id_ == other_constant->unique_id_; | 3453 unique_id_ == other_constant->unique_id_; |
3442 } | 3454 } |
3443 } | 3455 } |
3444 | 3456 |
3445 private: | 3457 private: |
3446 void Initialize(Representation r); | 3458 void Initialize(Representation r); |
3447 | 3459 |
3448 virtual bool IsDeletable() const { return true; } | 3460 virtual bool IsDeletable() const { return true; } |
3449 | 3461 |
3450 // If this is a numerical constant, handle_ either points to to the | 3462 // If this is a numerical constant, handle_ either points to to the |
3451 // HeapObject the constant originated from or is null. If the | 3463 // HeapObject the constant originated from or is null. If the |
3452 // constant is non-numeric, handle_ always points to a valid | 3464 // constant is non-numeric, handle_ always points to a valid |
3453 // constant HeapObject. | 3465 // constant HeapObject. |
3454 Handle<Object> handle_; | 3466 Handle<Object> handle_; |
3455 UniqueValueId unique_id_; | 3467 UniqueValueId unique_id_; |
3456 | 3468 |
3457 // We store the HConstant in the most specific form safely possible. | 3469 // We store the HConstant in the most specific form safely possible. |
3458 // The two flags, has_int32_value_ and has_double_value_ tell us if | 3470 // The two flags, has_int32_value_ and has_double_value_ tell us if |
3459 // int32_value_ and double_value_ hold valid, safe representations | 3471 // int32_value_ and double_value_ hold valid, safe representations |
3460 // of the constant. has_int32_value_ implies has_double_value_ but | 3472 // of the constant. has_int32_value_ implies has_double_value_ but |
3461 // not the converse. | 3473 // not the converse. |
3462 bool has_smi_value_ : 1; | 3474 bool has_smi_value_ : 1; |
3463 bool has_int32_value_ : 1; | 3475 bool has_int32_value_ : 1; |
3464 bool has_double_value_ : 1; | 3476 bool has_double_value_ : 1; |
3477 bool has_external_value_ : 1; | |
3465 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. | 3478 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
3466 bool is_not_in_new_space_ : 1; | 3479 bool is_not_in_new_space_ : 1; |
3467 bool is_cell_ : 1; | 3480 bool is_cell_ : 1; |
3468 bool boolean_value_ : 1; | 3481 bool boolean_value_ : 1; |
3469 int32_t int32_value_; | 3482 int32_t int32_value_; |
3470 double double_value_; | 3483 double double_value_; |
3484 ExternalReference external_value_; | |
3471 HType type_from_value_; | 3485 HType type_from_value_; |
3472 }; | 3486 }; |
3473 | 3487 |
3474 | 3488 |
3475 class HBinaryOperation: public HTemplateInstruction<3> { | 3489 class HBinaryOperation: public HTemplateInstruction<3> { |
3476 public: | 3490 public: |
3477 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3491 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
3478 : observed_output_representation_(Representation::None()) { | 3492 : observed_output_representation_(Representation::None()) { |
3479 ASSERT(left != NULL && right != NULL); | 3493 ASSERT(left != NULL && right != NULL); |
3480 SetOperandAt(0, context); | 3494 SetOperandAt(0, context); |
(...skipping 3213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6694 virtual bool IsDeletable() const { return true; } | 6708 virtual bool IsDeletable() const { return true; } |
6695 }; | 6709 }; |
6696 | 6710 |
6697 | 6711 |
6698 #undef DECLARE_INSTRUCTION | 6712 #undef DECLARE_INSTRUCTION |
6699 #undef DECLARE_CONCRETE_INSTRUCTION | 6713 #undef DECLARE_CONCRETE_INSTRUCTION |
6700 | 6714 |
6701 } } // namespace v8::internal | 6715 } } // namespace v8::internal |
6702 | 6716 |
6703 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6717 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |