Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: src/hydrogen-instructions.h

Issue 19562003: Add support for IncrementCounter in Hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: And another try Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 V(BackingStoreFields) \ 204 V(BackingStoreFields) \
205 V(Calls) \ 205 V(Calls) \
206 V(ContextSlots) \ 206 V(ContextSlots) \
207 V(DoubleArrayElements) \ 207 V(DoubleArrayElements) \
208 V(DoubleFields) \ 208 V(DoubleFields) \
209 V(ElementsKind) \ 209 V(ElementsKind) \
210 V(ElementsPointer) \ 210 V(ElementsPointer) \
211 V(GlobalVars) \ 211 V(GlobalVars) \
212 V(InobjectFields) \ 212 V(InobjectFields) \
213 V(OsrEntries) \ 213 V(OsrEntries) \
214 V(SpecializedArrayElements) 214 V(ExternalMemory)
215 215
216 216
217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ 217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \
218 virtual bool Is##type() const { return true; } \ 218 virtual bool Is##type() const { return true; } \
219 static H##type* cast(HValue* value) { \ 219 static H##type* cast(HValue* value) { \
220 ASSERT(value->Is##type()); \ 220 ASSERT(value->Is##type()); \
221 return reinterpret_cast<H##type*>(value); \ 221 return reinterpret_cast<H##type*>(value); \
222 } 222 }
223 223
224 224
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 static HType None() { return HType(kNone); }
353 static HType Tagged() { return HType(kTagged); } 354 static HType Tagged() { return HType(kTagged); }
354 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } 355 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
355 static HType TaggedNumber() { return HType(kTaggedNumber); } 356 static HType TaggedNumber() { return HType(kTaggedNumber); }
356 static HType Smi() { return HType(kSmi); } 357 static HType Smi() { return HType(kSmi); }
357 static HType HeapNumber() { return HType(kHeapNumber); } 358 static HType HeapNumber() { return HType(kHeapNumber); }
358 static HType String() { return HType(kString); } 359 static HType String() { return HType(kString); }
359 static HType Boolean() { return HType(kBoolean); } 360 static HType Boolean() { return HType(kBoolean); }
360 static HType NonPrimitive() { return HType(kNonPrimitive); } 361 static HType NonPrimitive() { return HType(kNonPrimitive); }
361 static HType JSArray() { return HType(kJSArray); } 362 static HType JSArray() { return HType(kJSArray); }
362 static HType JSObject() { return HType(kJSObject); } 363 static HType JSObject() { return HType(kJSObject); }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 } 441 }
441 return !representation.IsSmiOrInteger32() && !representation.IsDouble(); 442 return !representation.IsSmiOrInteger32() && !representation.IsDouble();
442 } 443 }
443 444
444 static HType TypeFromValue(Handle<Object> value); 445 static HType TypeFromValue(Handle<Object> value);
445 446
446 const char* ToString(); 447 const char* ToString();
447 448
448 private: 449 private:
449 enum Type { 450 enum Type {
451 kNone = 0x0, // 0000 0000 0000 0000
450 kTagged = 0x1, // 0000 0000 0000 0001 452 kTagged = 0x1, // 0000 0000 0000 0001
451 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 453 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
452 kTaggedNumber = 0xd, // 0000 0000 0000 1101 454 kTaggedNumber = 0xd, // 0000 0000 0000 1101
453 kSmi = 0x1d, // 0000 0000 0001 1101 455 kSmi = 0x1d, // 0000 0000 0001 1101
454 kHeapNumber = 0x2d, // 0000 0000 0010 1101 456 kHeapNumber = 0x2d, // 0000 0000 0010 1101
455 kString = 0x45, // 0000 0000 0100 0101 457 kString = 0x45, // 0000 0000 0100 0101
456 kBoolean = 0x85, // 0000 0000 1000 0101 458 kBoolean = 0x85, // 0000 0000 1000 0101
457 kNonPrimitive = 0x101, // 0000 0001 0000 0001 459 kNonPrimitive = 0x101, // 0000 0001 0000 0001
458 kJSObject = 0x301, // 0000 0011 0000 0001 460 kJSObject = 0x301, // 0000 0011 0000 0001
459 kJSArray = 0x701 // 0000 0111 0000 0001 461 kJSArray = 0x701 // 0000 0111 0000 0001
(...skipping 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2686 // change. The external array of a specialized array elements object cannot 2688 // change. The external array of a specialized array elements object cannot
2687 // change once set, so it's no necessary to introduce any additional 2689 // change once set, so it's no necessary to introduce any additional
2688 // dependencies on top of the inputs. 2690 // dependencies on top of the inputs.
2689 SetFlag(kUseGVN); 2691 SetFlag(kUseGVN);
2690 } 2692 }
2691 2693
2692 virtual Representation RequiredInputRepresentation(int index) { 2694 virtual Representation RequiredInputRepresentation(int index) {
2693 return Representation::Tagged(); 2695 return Representation::Tagged();
2694 } 2696 }
2695 2697
2698 virtual HType CalculateInferredType() {
2699 return HType::None();
2700 }
2701
2696 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) 2702 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
2697 2703
2698 protected: 2704 protected:
2699 virtual bool DataEquals(HValue* other) { return true; } 2705 virtual bool DataEquals(HValue* other) { return true; }
2700 2706
2701 private: 2707 private:
2702 virtual bool IsDeletable() const { return true; } 2708 virtual bool IsDeletable() const { return true; }
2703 }; 2709 };
2704 2710
2705 2711
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
3471 bool is_not_in_new_space = true, 3477 bool is_not_in_new_space = true,
3472 Handle<Object> optional_handle = Handle<Object>::null()); 3478 Handle<Object> optional_handle = Handle<Object>::null());
3473 HConstant(Handle<Object> handle, 3479 HConstant(Handle<Object> handle,
3474 UniqueValueId unique_id, 3480 UniqueValueId unique_id,
3475 Representation r, 3481 Representation r,
3476 HType type, 3482 HType type,
3477 bool is_internalized_string, 3483 bool is_internalized_string,
3478 bool is_not_in_new_space, 3484 bool is_not_in_new_space,
3479 bool is_cell, 3485 bool is_cell,
3480 bool boolean_value); 3486 bool boolean_value);
3487 explicit HConstant(ExternalReference reference);
3481 3488
3482 Handle<Object> handle() { 3489 Handle<Object> handle() {
3483 if (handle_.is_null()) { 3490 if (handle_.is_null()) {
3484 Factory* factory = Isolate::Current()->factory(); 3491 Factory* factory = Isolate::Current()->factory();
3485 // Default arguments to is_not_in_new_space depend on this heap number 3492 // Default arguments to is_not_in_new_space depend on this heap number
3486 // to be tenured so that it's guaranteed not be be located in new space. 3493 // to be tenured so that it's guaranteed not be be located in new space.
3487 handle_ = factory->NewNumber(double_value_, TENURED); 3494 handle_ = factory->NewNumber(double_value_, TENURED);
3488 } 3495 }
3489 AllowDeferredHandleDereference smi_check; 3496 AllowDeferredHandleDereference smi_check;
3490 ASSERT(has_int32_value_ || !handle_->IsSmi()); 3497 ASSERT(has_int32_value_ || !handle_->IsSmi());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3535 } 3542 }
3536 3543
3537 virtual Representation RequiredInputRepresentation(int index) { 3544 virtual Representation RequiredInputRepresentation(int index) {
3538 return Representation::None(); 3545 return Representation::None();
3539 } 3546 }
3540 3547
3541 virtual Representation KnownOptimalRepresentation() { 3548 virtual Representation KnownOptimalRepresentation() {
3542 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); 3549 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
3543 if (HasInteger32Value()) return Representation::Integer32(); 3550 if (HasInteger32Value()) return Representation::Integer32();
3544 if (HasNumberValue()) return Representation::Double(); 3551 if (HasNumberValue()) return Representation::Double();
3552 if (HasExternalReferenceValue()) return Representation::External();
3545 return Representation::Tagged(); 3553 return Representation::Tagged();
3546 } 3554 }
3547 3555
3548 virtual bool EmitAtUses(); 3556 virtual bool EmitAtUses();
3549 virtual void PrintDataTo(StringStream* stream); 3557 virtual void PrintDataTo(StringStream* stream);
3550 bool IsInteger() { return handle()->IsSmi(); } 3558 bool IsInteger() { return handle()->IsSmi(); }
3551 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; 3559 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
3552 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); 3560 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
3553 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); 3561 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone);
3554 bool HasInteger32Value() const { return has_int32_value_; } 3562 bool HasInteger32Value() const { return has_int32_value_; }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3586 return type_.IsString(); 3594 return type_.IsString();
3587 } 3595 }
3588 Handle<String> StringValue() const { 3596 Handle<String> StringValue() const {
3589 ASSERT(HasStringValue()); 3597 ASSERT(HasStringValue());
3590 return Handle<String>::cast(handle_); 3598 return Handle<String>::cast(handle_);
3591 } 3599 }
3592 bool HasInternalizedStringValue() const { 3600 bool HasInternalizedStringValue() const {
3593 return HasStringValue() && is_internalized_string_; 3601 return HasStringValue() && is_internalized_string_;
3594 } 3602 }
3595 3603
3604 bool HasExternalReferenceValue() const {
3605 return has_external_reference_value_;
3606 }
3607 ExternalReference ExternalReferenceValue() const {
3608 return external_reference_value_;
3609 }
3610
3596 bool BooleanValue() const { return boolean_value_; } 3611 bool BooleanValue() const { return boolean_value_; }
3597 3612
3598 virtual intptr_t Hashcode() { 3613 virtual intptr_t Hashcode() {
3599 if (has_int32_value_) { 3614 if (has_int32_value_) {
3600 return static_cast<intptr_t>(int32_value_); 3615 return static_cast<intptr_t>(int32_value_);
3601 } else if (has_double_value_) { 3616 } else if (has_double_value_) {
3602 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); 3617 return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3618 } else if (has_external_reference_value_) {
3619 return reinterpret_cast<intptr_t>(external_reference_value_.address());
3603 } else { 3620 } else {
3604 ASSERT(!handle_.is_null()); 3621 ASSERT(!handle_.is_null());
3605 return unique_id_.Hashcode(); 3622 return unique_id_.Hashcode();
3606 } 3623 }
3607 } 3624 }
3608 3625
3609 virtual void FinalizeUniqueValueId() { 3626 virtual void FinalizeUniqueValueId() {
3610 if (!has_double_value_) { 3627 if (!has_double_value_ && !has_external_reference_value_) {
3611 ASSERT(!handle_.is_null()); 3628 ASSERT(!handle_.is_null());
3612 unique_id_ = UniqueValueId(handle_); 3629 unique_id_ = UniqueValueId(handle_);
3613 } 3630 }
3614 } 3631 }
3615 3632
3616 bool UniqueValueIdsMatch(UniqueValueId other) { 3633 bool UniqueValueIdsMatch(UniqueValueId other) {
3617 return !has_double_value_ && unique_id_ == other; 3634 return !has_double_value_ && !has_external_reference_value_ &&
3635 unique_id_ == other;
3618 } 3636 }
3619 3637
3620 #ifdef DEBUG 3638 #ifdef DEBUG
3621 virtual void Verify() { } 3639 virtual void Verify() { }
3622 #endif 3640 #endif
3623 3641
3624 DECLARE_CONCRETE_INSTRUCTION(Constant) 3642 DECLARE_CONCRETE_INSTRUCTION(Constant)
3625 3643
3626 protected: 3644 protected:
3627 virtual Range* InferRange(Zone* zone); 3645 virtual Range* InferRange(Zone* zone);
3628 3646
3629 virtual bool DataEquals(HValue* other) { 3647 virtual bool DataEquals(HValue* other) {
3630 HConstant* other_constant = HConstant::cast(other); 3648 HConstant* other_constant = HConstant::cast(other);
3631 if (has_int32_value_) { 3649 if (has_int32_value_) {
3632 return other_constant->has_int32_value_ && 3650 return other_constant->has_int32_value_ &&
3633 int32_value_ == other_constant->int32_value_; 3651 int32_value_ == other_constant->int32_value_;
3634 } else if (has_double_value_) { 3652 } else if (has_double_value_) {
3635 return other_constant->has_double_value_ && 3653 return other_constant->has_double_value_ &&
3636 BitCast<int64_t>(double_value_) == 3654 BitCast<int64_t>(double_value_) ==
3637 BitCast<int64_t>(other_constant->double_value_); 3655 BitCast<int64_t>(other_constant->double_value_);
3656 } else if (has_external_reference_value_) {
3657 return other_constant->has_external_reference_value_ &&
3658 external_reference_value_ ==
3659 other_constant->external_reference_value_;
3638 } else { 3660 } else {
3639 ASSERT(!handle_.is_null()); 3661 ASSERT(!handle_.is_null());
3640 return !other_constant->handle_.is_null() && 3662 return !other_constant->handle_.is_null() &&
3641 unique_id_ == other_constant->unique_id_; 3663 unique_id_ == other_constant->unique_id_;
3642 } 3664 }
3643 } 3665 }
3644 3666
3645 private: 3667 private:
3646 void Initialize(Representation r); 3668 void Initialize(Representation r);
3647 3669
3648 virtual bool IsDeletable() const { return true; } 3670 virtual bool IsDeletable() const { return true; }
3649 3671
3650 // If this is a numerical constant, handle_ either points to to the 3672 // If this is a numerical constant, handle_ either points to to the
3651 // HeapObject the constant originated from or is null. If the 3673 // HeapObject the constant originated from or is null. If the
3652 // constant is non-numeric, handle_ always points to a valid 3674 // constant is non-numeric, handle_ always points to a valid
3653 // constant HeapObject. 3675 // constant HeapObject.
3654 Handle<Object> handle_; 3676 Handle<Object> handle_;
3655 UniqueValueId unique_id_; 3677 UniqueValueId unique_id_;
3656 3678
3657 // We store the HConstant in the most specific form safely possible. 3679 // We store the HConstant in the most specific form safely possible.
3658 // The two flags, has_int32_value_ and has_double_value_ tell us if 3680 // The two flags, has_int32_value_ and has_double_value_ tell us if
3659 // int32_value_ and double_value_ hold valid, safe representations 3681 // int32_value_ and double_value_ hold valid, safe representations
3660 // of the constant. has_int32_value_ implies has_double_value_ but 3682 // of the constant. has_int32_value_ implies has_double_value_ but
3661 // not the converse. 3683 // not the converse.
3662 bool has_smi_value_ : 1; 3684 bool has_smi_value_ : 1;
3663 bool has_int32_value_ : 1; 3685 bool has_int32_value_ : 1;
3664 bool has_double_value_ : 1; 3686 bool has_double_value_ : 1;
3687 bool has_external_reference_value_ : 1;
3665 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. 3688 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
3666 bool is_not_in_new_space_ : 1; 3689 bool is_not_in_new_space_ : 1;
3667 bool is_cell_ : 1; 3690 bool is_cell_ : 1;
3668 bool boolean_value_ : 1; 3691 bool boolean_value_ : 1;
3669 int32_t int32_value_; 3692 int32_t int32_value_;
3670 double double_value_; 3693 double double_value_;
3694 ExternalReference external_reference_value_;
3671 }; 3695 };
3672 3696
3673 3697
3674 class HBinaryOperation: public HTemplateInstruction<3> { 3698 class HBinaryOperation: public HTemplateInstruction<3> {
3675 public: 3699 public:
3676 HBinaryOperation(HValue* context, HValue* left, HValue* right) 3700 HBinaryOperation(HValue* context, HValue* left, HValue* right)
3677 : observed_output_representation_(Representation::None()) { 3701 : observed_output_representation_(Representation::None()) {
3678 ASSERT(left != NULL && right != NULL); 3702 ASSERT(left != NULL && right != NULL);
3679 SetOperandAt(0, context); 3703 SetOperandAt(0, context);
3680 SetOperandAt(1, left); 3704 SetOperandAt(1, left);
(...skipping 1876 matching lines...) Expand 10 before | Expand all | Expand 10 after
5557 int slot_index_; 5581 int slot_index_;
5558 Mode mode_; 5582 Mode mode_;
5559 }; 5583 };
5560 5584
5561 5585
5562 // Represents an access to a portion of an object, such as the map pointer, 5586 // Represents an access to a portion of an object, such as the map pointer,
5563 // array elements pointer, etc, but not accesses to array elements themselves. 5587 // array elements pointer, etc, but not accesses to array elements themselves.
5564 class HObjectAccess { 5588 class HObjectAccess {
5565 public: 5589 public:
5566 inline bool IsInobject() const { 5590 inline bool IsInobject() const {
5567 return portion() != kBackingStore; 5591 return portion() != kBackingStore && portion() != kExternalMemory;
5592 }
5593
5594 inline bool IsExternalMemory() const {
5595 return portion() == kExternalMemory;
5568 } 5596 }
5569 5597
5570 inline int offset() const { 5598 inline int offset() const {
5571 return OffsetField::decode(value_); 5599 return OffsetField::decode(value_);
5572 } 5600 }
5573 5601
5574 inline Representation representation() const { 5602 inline Representation representation() const {
5575 return Representation::FromKind(RepresentationField::decode(value_)); 5603 return Representation::FromKind(RepresentationField::decode(value_));
5576 } 5604 }
5577 5605
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
5633 } 5661 }
5634 5662
5635 static HObjectAccess ForCellValue() { 5663 static HObjectAccess ForCellValue() {
5636 return HObjectAccess(kInobject, Cell::kValueOffset); 5664 return HObjectAccess(kInobject, Cell::kValueOffset);
5637 } 5665 }
5638 5666
5639 static HObjectAccess ForAllocationMementoSite() { 5667 static HObjectAccess ForAllocationMementoSite() {
5640 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); 5668 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
5641 } 5669 }
5642 5670
5671 static HObjectAccess ForCounter() {
5672 return HObjectAccess(kExternalMemory, 0, Representation::Integer32());
5673 }
5674
5643 // Create an access to an offset in a fixed array header. 5675 // Create an access to an offset in a fixed array header.
5644 static HObjectAccess ForFixedArrayHeader(int offset); 5676 static HObjectAccess ForFixedArrayHeader(int offset);
5645 5677
5646 // Create an access to an in-object property in a JSObject. 5678 // Create an access to an in-object property in a JSObject.
5647 static HObjectAccess ForJSObjectOffset(int offset, 5679 static HObjectAccess ForJSObjectOffset(int offset,
5648 Representation representation = Representation::Tagged()); 5680 Representation representation = Representation::Tagged());
5649 5681
5650 // Create an access to an in-object property in a JSArray. 5682 // Create an access to an in-object property in a JSArray.
5651 static HObjectAccess ForJSArrayOffset(int offset); 5683 static HObjectAccess ForJSArrayOffset(int offset);
5652 5684
(...skipping 18 matching lines...) Expand all
5671 void SetGVNFlags(HValue *instr, bool is_store); 5703 void SetGVNFlags(HValue *instr, bool is_store);
5672 5704
5673 private: 5705 private:
5674 // internal use only; different parts of an object or array 5706 // internal use only; different parts of an object or array
5675 enum Portion { 5707 enum Portion {
5676 kMaps, // map of an object 5708 kMaps, // map of an object
5677 kArrayLengths, // the length of an array 5709 kArrayLengths, // the length of an array
5678 kElementsPointer, // elements pointer 5710 kElementsPointer, // elements pointer
5679 kBackingStore, // some field in the backing store 5711 kBackingStore, // some field in the backing store
5680 kDouble, // some double field 5712 kDouble, // some double field
5681 kInobject // some other in-object field 5713 kInobject, // some other in-object field
5714 kExternalMemory // some field in external memory
5682 }; 5715 };
5683 5716
5684 HObjectAccess(Portion portion, int offset, 5717 HObjectAccess(Portion portion, int offset,
5685 Representation representation = Representation::Tagged(), 5718 Representation representation = Representation::Tagged(),
5686 Handle<String> name = Handle<String>::null()) 5719 Handle<String> name = Handle<String>::null())
5687 : value_(PortionField::encode(portion) | 5720 : value_(PortionField::encode(portion) |
5688 RepresentationField::encode(representation.kind()) | 5721 RepresentationField::encode(representation.kind()) |
5689 OffsetField::encode(offset)), 5722 OffsetField::encode(offset)),
5690 name_(name) { 5723 name_(name) {
5691 // assert that the fields decode correctly 5724 // assert that the fields decode correctly
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
5749 HValue* typecheck = NULL) 5782 HValue* typecheck = NULL)
5750 : access_(access) { 5783 : access_(access) {
5751 ASSERT(object != NULL); 5784 ASSERT(object != NULL);
5752 SetOperandAt(0, object); 5785 SetOperandAt(0, object);
5753 SetOperandAt(1, typecheck != NULL ? typecheck : object); 5786 SetOperandAt(1, typecheck != NULL ? typecheck : object);
5754 5787
5755 Representation representation = access.representation(); 5788 Representation representation = access.representation();
5756 if (representation.IsSmi()) { 5789 if (representation.IsSmi()) {
5757 set_type(HType::Smi()); 5790 set_type(HType::Smi());
5758 set_representation(representation); 5791 set_representation(representation);
5759 } else if (representation.IsDouble()) { 5792 } else if (representation.IsDouble() ||
5793 representation.IsExternal() ||
5794 representation.IsInteger32()) {
5760 set_representation(representation); 5795 set_representation(representation);
5761 } else if (FLAG_track_heap_object_fields && 5796 } else if (FLAG_track_heap_object_fields &&
5762 representation.IsHeapObject()) { 5797 representation.IsHeapObject()) {
5763 set_type(HType::NonPrimitive()); 5798 set_type(HType::NonPrimitive());
5764 set_representation(Representation::Tagged()); 5799 set_representation(Representation::Tagged());
5765 } else { 5800 } else {
5766 set_representation(Representation::Tagged()); 5801 set_representation(Representation::Tagged());
5767 } 5802 }
5768 access.SetGVNFlags(this, false); 5803 access.SetGVNFlags(this, false);
5769 } 5804 }
5770 5805
5771 HValue* object() { return OperandAt(0); } 5806 HValue* object() { return OperandAt(0); }
5772 HValue* typecheck() { 5807 HValue* typecheck() {
5773 ASSERT(HasTypeCheck()); 5808 ASSERT(HasTypeCheck());
5774 return OperandAt(1); 5809 return OperandAt(1);
5775 } 5810 }
5776 5811
5777 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } 5812 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
5778 HObjectAccess access() const { return access_; } 5813 HObjectAccess access() const { return access_; }
5779 Representation field_representation() const { 5814 Representation field_representation() const {
5780 return access_.representation(); 5815 return access_.representation();
5781 } 5816 }
5782 5817
5783 virtual bool HasEscapingOperandAt(int index) { return false; } 5818 virtual bool HasEscapingOperandAt(int index) { return false; }
5784 virtual Representation RequiredInputRepresentation(int index) { 5819 virtual Representation RequiredInputRepresentation(int index) {
5820 if (index == 0 && access().IsExternalMemory()) {
5821 // object must be external in case of external memory access
5822 return Representation::External();
5823 }
5785 return Representation::Tagged(); 5824 return Representation::Tagged();
5786 } 5825 }
5787 virtual void PrintDataTo(StringStream* stream); 5826 virtual void PrintDataTo(StringStream* stream);
5788 5827
5789 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) 5828 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
5790 5829
5791 protected: 5830 protected:
5792 virtual bool DataEquals(HValue* other) { 5831 virtual bool DataEquals(HValue* other) {
5793 HLoadNamedField* b = HLoadNamedField::cast(other); 5832 HLoadNamedField* b = HLoadNamedField::cast(other);
5794 return access_.Equals(b->access_); 5833 return access_.Equals(b->access_);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
5948 SetGVNFlag(kDependsOnDoubleArrayElements); 5987 SetGVNFlag(kDependsOnDoubleArrayElements);
5949 } 5988 }
5950 } else { 5989 } else {
5951 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 5990 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
5952 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 5991 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
5953 set_representation(Representation::Double()); 5992 set_representation(Representation::Double());
5954 } else { 5993 } else {
5955 set_representation(Representation::Integer32()); 5994 set_representation(Representation::Integer32());
5956 } 5995 }
5957 5996
5958 SetGVNFlag(kDependsOnSpecializedArrayElements); 5997 SetGVNFlag(kDependsOnExternalMemory);
5959 // Native code could change the specialized array. 5998 // Native code could change the specialized array.
5960 SetGVNFlag(kDependsOnCalls); 5999 SetGVNFlag(kDependsOnCalls);
5961 } 6000 }
5962 6001
5963 SetFlag(kUseGVN); 6002 SetFlag(kUseGVN);
5964 } 6003 }
5965 6004
5966 bool is_external() const { 6005 bool is_external() const {
5967 return IsExternalArrayElementsKind(elements_kind()); 6006 return IsExternalArrayElementsKind(elements_kind());
5968 } 6007 }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
6105 write_barrier_mode_(UPDATE_WRITE_BARRIER) { 6144 write_barrier_mode_(UPDATE_WRITE_BARRIER) {
6106 SetOperandAt(0, obj); 6145 SetOperandAt(0, obj);
6107 SetOperandAt(1, val); 6146 SetOperandAt(1, val);
6108 access.SetGVNFlags(this, true); 6147 access.SetGVNFlags(this, true);
6109 } 6148 }
6110 6149
6111 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 6150 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
6112 6151
6113 virtual bool HasEscapingOperandAt(int index) { return index == 1; } 6152 virtual bool HasEscapingOperandAt(int index) { return index == 1; }
6114 virtual Representation RequiredInputRepresentation(int index) { 6153 virtual Representation RequiredInputRepresentation(int index) {
6115 if (index == 1 && field_representation().IsDouble()) { 6154 if (index == 0 && access().IsExternalMemory()) {
6116 return field_representation(); 6155 // object must be external in case of external memory access
6117 } else if (index == 1 && field_representation().IsSmi()) { 6156 return Representation::External();
6157 } else if (index == 1 &&
6158 (field_representation().IsDouble() ||
6159 field_representation().IsSmi() ||
6160 field_representation().IsInteger32())) {
6118 return field_representation(); 6161 return field_representation();
6119 } 6162 }
6120 return Representation::Tagged(); 6163 return Representation::Tagged();
6121 } 6164 }
6122 virtual void HandleSideEffectDominator(GVNFlag side_effect, 6165 virtual void HandleSideEffectDominator(GVNFlag side_effect,
6123 HValue* dominator) { 6166 HValue* dominator) {
6124 ASSERT(side_effect == kChangesNewSpacePromotion); 6167 ASSERT(side_effect == kChangesNewSpacePromotion);
6125 new_space_dominator_ = dominator; 6168 new_space_dominator_ = dominator;
6126 } 6169 }
6127 virtual void PrintDataTo(StringStream* stream); 6170 virtual void PrintDataTo(StringStream* stream);
(...skipping 17 matching lines...) Expand all
6145 transition_ = map; 6188 transition_ = map;
6146 } 6189 }
6147 HValue* new_space_dominator() const { return new_space_dominator_; } 6190 HValue* new_space_dominator() const { return new_space_dominator_; }
6148 6191
6149 bool NeedsWriteBarrier() { 6192 bool NeedsWriteBarrier() {
6150 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || 6193 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) ||
6151 transition_.is_null()); 6194 transition_.is_null());
6152 if (IsSkipWriteBarrier()) return false; 6195 if (IsSkipWriteBarrier()) return false;
6153 if (field_representation().IsDouble()) return false; 6196 if (field_representation().IsDouble()) return false;
6154 if (field_representation().IsSmi()) return false; 6197 if (field_representation().IsSmi()) return false;
6198 if (field_representation().IsInteger32()) return false;
6155 return StoringValueNeedsWriteBarrier(value()) && 6199 return StoringValueNeedsWriteBarrier(value()) &&
6156 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 6200 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
6157 } 6201 }
6158 6202
6159 bool NeedsWriteBarrierForMap() { 6203 bool NeedsWriteBarrierForMap() {
6160 if (IsSkipWriteBarrier()) return false; 6204 if (IsSkipWriteBarrier()) return false;
6161 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 6205 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
6162 } 6206 }
6163 6207
6164 virtual void FinalizeUniqueValueId() { 6208 virtual void FinalizeUniqueValueId() {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
6225 new_space_dominator_(NULL) { 6269 new_space_dominator_(NULL) {
6226 SetOperandAt(0, obj); 6270 SetOperandAt(0, obj);
6227 SetOperandAt(1, key); 6271 SetOperandAt(1, key);
6228 SetOperandAt(2, val); 6272 SetOperandAt(2, val);
6229 6273
6230 if (IsFastObjectElementsKind(elements_kind)) { 6274 if (IsFastObjectElementsKind(elements_kind)) {
6231 SetFlag(kTrackSideEffectDominators); 6275 SetFlag(kTrackSideEffectDominators);
6232 SetGVNFlag(kDependsOnNewSpacePromotion); 6276 SetGVNFlag(kDependsOnNewSpacePromotion);
6233 } 6277 }
6234 if (is_external()) { 6278 if (is_external()) {
6235 SetGVNFlag(kChangesSpecializedArrayElements); 6279 SetGVNFlag(kChangesExternalMemory);
6236 SetFlag(kAllowUndefinedAsNaN); 6280 SetFlag(kAllowUndefinedAsNaN);
6237 } else if (IsFastDoubleElementsKind(elements_kind)) { 6281 } else if (IsFastDoubleElementsKind(elements_kind)) {
6238 SetGVNFlag(kChangesDoubleArrayElements); 6282 SetGVNFlag(kChangesDoubleArrayElements);
6239 } else if (IsFastSmiElementsKind(elements_kind)) { 6283 } else if (IsFastSmiElementsKind(elements_kind)) {
6240 SetGVNFlag(kChangesArrayElements); 6284 SetGVNFlag(kChangesArrayElements);
6241 } else { 6285 } else {
6242 SetGVNFlag(kChangesArrayElements); 6286 SetGVNFlag(kChangesArrayElements);
6243 } 6287 }
6244 6288
6245 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 6289 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
6962 virtual bool IsDeletable() const { return true; } 7006 virtual bool IsDeletable() const { return true; }
6963 }; 7007 };
6964 7008
6965 7009
6966 #undef DECLARE_INSTRUCTION 7010 #undef DECLARE_INSTRUCTION
6967 #undef DECLARE_CONCRETE_INSTRUCTION 7011 #undef DECLARE_CONCRETE_INSTRUCTION
6968 7012
6969 } } // namespace v8::internal 7013 } } // namespace v8::internal
6970 7014
6971 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 7015 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698