| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 class HValue; | 51 class HValue; |
| 52 class LInstruction; | 52 class LInstruction; |
| 53 class LChunkBuilder; | 53 class LChunkBuilder; |
| 54 | 54 |
| 55 | 55 |
| 56 #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \ | 56 #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \ |
| 57 V(BinaryOperation) \ | 57 V(BinaryOperation) \ |
| 58 V(BitwiseBinaryOperation) \ | 58 V(BitwiseBinaryOperation) \ |
| 59 V(ControlInstruction) \ | 59 V(ControlInstruction) \ |
| 60 V(Instruction) \ | 60 V(Instruction) \ |
| 61 V(ArrayInstruction) \ |
| 61 | 62 |
| 62 | 63 |
| 63 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ | 64 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ |
| 64 V(AbnormalExit) \ | 65 V(AbnormalExit) \ |
| 65 V(AccessArgumentsAt) \ | 66 V(AccessArgumentsAt) \ |
| 66 V(Add) \ | 67 V(Add) \ |
| 67 V(AllocateObject) \ | 68 V(AllocateObject) \ |
| 68 V(ApplyArguments) \ | 69 V(ApplyArguments) \ |
| 69 V(ArgumentsElements) \ | 70 V(ArgumentsElements) \ |
| 70 V(ArgumentsLength) \ | 71 V(ArgumentsLength) \ |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 flags_(0) {} | 628 flags_(0) {} |
| 628 virtual ~HValue() {} | 629 virtual ~HValue() {} |
| 629 | 630 |
| 630 HBasicBlock* block() const { return block_; } | 631 HBasicBlock* block() const { return block_; } |
| 631 void SetBlock(HBasicBlock* block); | 632 void SetBlock(HBasicBlock* block); |
| 632 int LoopWeight() const; | 633 int LoopWeight() const; |
| 633 | 634 |
| 634 int id() const { return id_; } | 635 int id() const { return id_; } |
| 635 void set_id(int id) { id_ = id; } | 636 void set_id(int id) { id_ = id; } |
| 636 | 637 |
| 638 // For participation in hashmaps |
| 639 uint32_t Hash() { |
| 640 ASSERT(id() != kNoNumber); |
| 641 return id(); |
| 642 } |
| 643 |
| 637 HUseIterator uses() const { return HUseIterator(use_list_); } | 644 HUseIterator uses() const { return HUseIterator(use_list_); } |
| 638 | 645 |
| 639 virtual bool EmitAtUses() { return false; } | 646 virtual bool EmitAtUses() { return false; } |
| 640 Representation representation() const { return representation_; } | 647 Representation representation() const { return representation_; } |
| 641 void ChangeRepresentation(Representation r) { | 648 void ChangeRepresentation(Representation r) { |
| 642 ASSERT(CheckFlag(kFlexibleRepresentation)); | 649 ASSERT(CheckFlag(kFlexibleRepresentation)); |
| 643 RepresentationChanged(r); | 650 RepresentationChanged(r); |
| 644 representation_ = r; | 651 representation_ = r; |
| 645 if (r.IsTagged()) { | 652 if (r.IsTagged()) { |
| 646 // Tagged is the bottom of the lattice, don't go any further. | 653 // Tagged is the bottom of the lattice, don't go any further. |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 HInstruction* next() const { return next_; } | 898 HInstruction* next() const { return next_; } |
| 892 HInstruction* previous() const { return previous_; } | 899 HInstruction* previous() const { return previous_; } |
| 893 | 900 |
| 894 virtual void PrintTo(StringStream* stream); | 901 virtual void PrintTo(StringStream* stream); |
| 895 virtual void PrintDataTo(StringStream* stream) { } | 902 virtual void PrintDataTo(StringStream* stream) { } |
| 896 | 903 |
| 897 bool IsLinked() const { return block() != NULL; } | 904 bool IsLinked() const { return block() != NULL; } |
| 898 void Unlink(); | 905 void Unlink(); |
| 899 void InsertBefore(HInstruction* next); | 906 void InsertBefore(HInstruction* next); |
| 900 void InsertAfter(HInstruction* previous); | 907 void InsertAfter(HInstruction* previous); |
| 908 bool IsDefinedAfterInSameBlock(HValue* other) const; |
| 901 | 909 |
| 902 // The position is a write-once variable. | 910 // The position is a write-once variable. |
| 903 int position() const { return position_; } | 911 int position() const { return position_; } |
| 904 bool has_position() const { return position_ != RelocInfo::kNoPosition; } | 912 bool has_position() const { return position_ != RelocInfo::kNoPosition; } |
| 905 void set_position(int position) { | 913 void set_position(int position) { |
| 906 ASSERT(!has_position()); | 914 ASSERT(!has_position()); |
| 907 ASSERT(position != RelocInfo::kNoPosition); | 915 ASSERT(position != RelocInfo::kNoPosition); |
| 908 position_ = position; | 916 position_ = position; |
| 909 } | 917 } |
| 910 | 918 |
| (...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2254 } | 2262 } |
| 2255 | 2263 |
| 2256 virtual Representation RequiredInputRepresentation(int index) { | 2264 virtual Representation RequiredInputRepresentation(int index) { |
| 2257 return Representation::Tagged(); | 2265 return Representation::Tagged(); |
| 2258 } | 2266 } |
| 2259 | 2267 |
| 2260 virtual void PrintDataTo(StringStream* stream); | 2268 virtual void PrintDataTo(StringStream* stream); |
| 2261 virtual HType CalculateInferredType(); | 2269 virtual HType CalculateInferredType(); |
| 2262 | 2270 |
| 2263 HValue* value() { return OperandAt(0); } | 2271 HValue* value() { return OperandAt(0); } |
| 2272 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
| 2273 void RemoveTypeCheck() { SetOperandAt(1, OperandAt(0)); } |
| 2264 SmallMapList* map_set() { return &map_set_; } | 2274 SmallMapList* map_set() { return &map_set_; } |
| 2265 | 2275 |
| 2266 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2276 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
| 2267 | 2277 |
| 2268 protected: | 2278 protected: |
| 2269 virtual bool DataEquals(HValue* other) { | 2279 virtual bool DataEquals(HValue* other) { |
| 2270 HCheckMaps* b = HCheckMaps::cast(other); | 2280 HCheckMaps* b = HCheckMaps::cast(other); |
| 2271 // Relies on the fact that map_set has been sorted before. | 2281 // Relies on the fact that map_set has been sorted before. |
| 2272 if (map_set()->length() != b->map_set()->length()) return false; | 2282 if (map_set()->length() != b->map_set()->length()) return false; |
| 2273 for (int i = 0; i < map_set()->length(); i++) { | 2283 for (int i = 0; i < map_set()->length(); i++) { |
| (...skipping 2062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4336 virtual Representation RequiredInputRepresentation(int index) { | 4346 virtual Representation RequiredInputRepresentation(int index) { |
| 4337 return Representation::Tagged(); | 4347 return Representation::Tagged(); |
| 4338 } | 4348 } |
| 4339 | 4349 |
| 4340 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) | 4350 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) |
| 4341 | 4351 |
| 4342 protected: | 4352 protected: |
| 4343 virtual bool DataEquals(HValue* other) { return true; } | 4353 virtual bool DataEquals(HValue* other) { return true; } |
| 4344 }; | 4354 }; |
| 4345 | 4355 |
| 4346 class ArrayInstructionInterface { | 4356 |
| 4357 class HTransitionElementsKind; |
| 4358 class HArrayInstruction: public HTemplateInstruction<3> { |
| 4347 public: | 4359 public: |
| 4348 virtual HValue* GetKey() = 0; | 4360 HArrayInstruction(HValue* obj, HValue* key, Zone* zone) : |
| 4349 virtual void SetKey(HValue* key) = 0; | 4361 zone_(zone), |
| 4362 transitions_(new(zone) ZoneList<HTransitionElementsKind*>(5, zone)), |
| 4363 hoistable_(true), |
| 4364 initialized_(false) { |
| 4365 SetOperandAt(0, obj); |
| 4366 SetOperandAt(1, key); |
| 4367 } |
| 4368 |
| 4369 HValue* elements() { return OperandAt(0); } |
| 4370 HValue* key() { return OperandAt(1); } |
| 4371 |
| 4372 HValue* GetKey() { return key(); } |
| 4373 void SetKey(HValue* key) { SetOperandAt(1, key); } |
| 4374 |
| 4375 virtual ElementsKind GetElementsKind() = 0; |
| 4350 virtual void SetIndexOffset(uint32_t index_offset) = 0; | 4376 virtual void SetIndexOffset(uint32_t index_offset) = 0; |
| 4351 virtual bool IsDehoisted() = 0; | 4377 virtual bool IsDehoisted() = 0; |
| 4352 virtual void SetDehoisted(bool is_dehoisted) = 0; | 4378 virtual void SetDehoisted(bool is_dehoisted) = 0; |
| 4353 virtual ~ArrayInstructionInterface() { }; | 4379 virtual void PerformDeferredInitialization( |
| 4354 }; | 4380 ElementsKind new_elements_kind) = 0; |
| 4381 virtual void PerformDeferredInitialization() = 0; |
| 4382 virtual ~HArrayInstruction() { }; |
| 4383 |
| 4384 void AddTransitions(const ZoneList<HTransitionElementsKind*>& |
| 4385 transition_list); |
| 4386 bool hoistable() const { return hoistable_; } |
| 4387 void set_hoistable(bool value) { hoistable_ = value; } |
| 4388 |
| 4389 int transitions() const { return transitions_->length(); } |
| 4390 HTransitionElementsKind* transition(int index) { |
| 4391 return transitions_->at(index); |
| 4392 } |
| 4393 |
| 4394 Handle<Map> map_family(); |
| 4395 |
| 4396 void Finalize(ElementsKind kind) { |
| 4397 if (!Initialized()) { |
| 4398 PerformDeferredInitialization(kind); |
| 4399 } |
| 4400 |
| 4401 // This will detect re-initialization |
| 4402 ASSERT(Initialized() && kind == GetElementsKind()); |
| 4403 } |
| 4404 |
| 4405 void Finalize() { |
| 4406 if (!Initialized()) { |
| 4407 PerformDeferredInitialization(); |
| 4408 } |
| 4409 } |
| 4410 |
| 4411 void PrintElementPlacementTo(StringStream* stream); |
| 4412 bool Initialized() const { return initialized_; } |
| 4413 |
| 4414 DECLARE_ABSTRACT_INSTRUCTION(ArrayInstruction) |
| 4415 |
| 4416 protected: |
| 4417 void SetInitialized() { initialized_ = true; } |
| 4418 |
| 4419 private: |
| 4420 Zone* zone_; |
| 4421 ZoneList<HTransitionElementsKind*>* transitions_; |
| 4422 bool hoistable_; |
| 4423 bool initialized_; |
| 4424 }; |
| 4355 | 4425 |
| 4356 | 4426 |
| 4357 class HLoadKeyed | 4427 class HLoadKeyed: public HArrayInstruction { |
| 4358 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | |
| 4359 public: | 4428 public: |
| 4360 HLoadKeyed(HValue* obj, | 4429 HLoadKeyed(HValue* obj, |
| 4361 HValue* key, | 4430 HValue* key, |
| 4362 HValue* dependency, | 4431 HValue* dependency, |
| 4363 ElementsKind elements_kind) | 4432 ElementsKind elements_kind, |
| 4364 : bit_field_(0) { | 4433 Zone* zone); |
| 4365 bit_field_ = ElementsKindField::encode(elements_kind); | |
| 4366 | 4434 |
| 4367 SetOperandAt(0, obj); | 4435 void PerformDeferredInitialization(ElementsKind new_elements_kind); |
| 4368 SetOperandAt(1, key); | 4436 void PerformDeferredInitialization() { |
| 4369 SetOperandAt(2, dependency); | 4437 PerformDeferredInitialization(elements_kind()); |
| 4370 | |
| 4371 if (!is_external()) { | |
| 4372 // I can detect the case between storing double (holey and fast) and | |
| 4373 // smi/object by looking at elements_kind_. | |
| 4374 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | |
| 4375 IsFastDoubleElementsKind(elements_kind)); | |
| 4376 | |
| 4377 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | |
| 4378 if (IsFastSmiElementsKind(elements_kind) && | |
| 4379 IsFastPackedElementsKind(elements_kind)) { | |
| 4380 set_type(HType::Smi()); | |
| 4381 } | |
| 4382 | |
| 4383 set_representation(Representation::Tagged()); | |
| 4384 SetGVNFlag(kDependsOnArrayElements); | |
| 4385 } else { | |
| 4386 set_representation(Representation::Double()); | |
| 4387 SetGVNFlag(kDependsOnDoubleArrayElements); | |
| 4388 } | |
| 4389 } else { | |
| 4390 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | |
| 4391 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | |
| 4392 set_representation(Representation::Double()); | |
| 4393 } else { | |
| 4394 set_representation(Representation::Integer32()); | |
| 4395 } | |
| 4396 | |
| 4397 SetGVNFlag(kDependsOnSpecializedArrayElements); | |
| 4398 // Native code could change the specialized array. | |
| 4399 SetGVNFlag(kDependsOnCalls); | |
| 4400 } | |
| 4401 | |
| 4402 SetFlag(kUseGVN); | |
| 4403 } | 4438 } |
| 4404 | 4439 |
| 4405 bool is_external() const { | 4440 bool is_external() const { |
| 4406 return IsExternalArrayElementsKind(elements_kind()); | 4441 return IsExternalArrayElementsKind(elements_kind()); |
| 4407 } | 4442 } |
| 4408 HValue* elements() { return OperandAt(0); } | |
| 4409 HValue* key() { return OperandAt(1); } | |
| 4410 HValue* dependency() { return OperandAt(2); } | 4443 HValue* dependency() { return OperandAt(2); } |
| 4411 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } | 4444 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } |
| 4412 void SetIndexOffset(uint32_t index_offset) { | 4445 void SetIndexOffset(uint32_t index_offset) { |
| 4413 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); | 4446 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); |
| 4414 } | 4447 } |
| 4415 HValue* GetKey() { return key(); } | |
| 4416 void SetKey(HValue* key) { SetOperandAt(1, key); } | |
| 4417 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 4448 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } |
| 4418 void SetDehoisted(bool is_dehoisted) { | 4449 void SetDehoisted(bool is_dehoisted) { |
| 4419 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 4450 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); |
| 4420 } | 4451 } |
| 4421 ElementsKind elements_kind() const { | 4452 ElementsKind elements_kind() const { |
| 4422 return ElementsKindField::decode(bit_field_); | 4453 return ElementsKindField::decode(bit_field_); |
| 4423 } | 4454 } |
| 4455 ElementsKind GetElementsKind() { |
| 4456 return elements_kind(); |
| 4457 } |
| 4424 | 4458 |
| 4425 virtual Representation RequiredInputRepresentation(int index) { | 4459 virtual Representation RequiredInputRepresentation(int index) { |
| 4460 ASSERT(Initialized()); |
| 4461 |
| 4426 // kind_fast: tagged[int32] (none) | 4462 // kind_fast: tagged[int32] (none) |
| 4427 // kind_double: tagged[int32] (none) | 4463 // kind_double: tagged[int32] (none) |
| 4428 // kind_external: external[int32] (none) | 4464 // kind_external: external[int32] (none) |
| 4429 if (index == 0) { | 4465 if (index == 0) { |
| 4430 return is_external() ? Representation::External() | 4466 return is_external() ? Representation::External() |
| 4431 : Representation::Tagged(); | 4467 : Representation::Tagged(); |
| 4432 } | 4468 } |
| 4433 if (index == 1) return Representation::Integer32(); | 4469 if (index == 1) return Representation::Integer32(); |
| 4434 return Representation::None(); | 4470 return Representation::None(); |
| 4435 } | 4471 } |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4604 } | 4640 } |
| 4605 | 4641 |
| 4606 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) | 4642 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) |
| 4607 | 4643 |
| 4608 private: | 4644 private: |
| 4609 Handle<String> name_; | 4645 Handle<String> name_; |
| 4610 StrictModeFlag strict_mode_flag_; | 4646 StrictModeFlag strict_mode_flag_; |
| 4611 }; | 4647 }; |
| 4612 | 4648 |
| 4613 | 4649 |
| 4614 class HStoreKeyed | 4650 class HStoreKeyed: public HArrayInstruction { |
| 4615 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | |
| 4616 public: | 4651 public: |
| 4617 HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 4652 HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
| 4618 ElementsKind elements_kind) | 4653 ElementsKind elements_kind, Zone* zone); |
| 4619 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | |
| 4620 SetOperandAt(0, obj); | |
| 4621 SetOperandAt(1, key); | |
| 4622 SetOperandAt(2, val); | |
| 4623 | 4654 |
| 4624 if (is_external()) { | 4655 void PerformDeferredInitialization(ElementsKind new_elements_kind); |
| 4625 SetGVNFlag(kChangesSpecializedArrayElements); | 4656 void PerformDeferredInitialization() { |
| 4626 } else if (IsFastDoubleElementsKind(elements_kind)) { | 4657 PerformDeferredInitialization(elements_kind()); |
| 4627 SetGVNFlag(kChangesDoubleArrayElements); | |
| 4628 SetFlag(kDeoptimizeOnUndefined); | |
| 4629 } else { | |
| 4630 SetGVNFlag(kChangesArrayElements); | |
| 4631 } | |
| 4632 | |
| 4633 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | |
| 4634 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | |
| 4635 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | |
| 4636 SetFlag(kTruncatingToInt32); | |
| 4637 } | |
| 4638 } | 4658 } |
| 4639 | 4659 |
| 4640 virtual Representation RequiredInputRepresentation(int index) { | 4660 virtual Representation RequiredInputRepresentation(int index) { |
| 4641 // kind_fast: tagged[int32] = tagged | 4661 // kind_fast: tagged[int32] = tagged |
| 4642 // kind_double: tagged[int32] = double | 4662 // kind_double: tagged[int32] = double |
| 4643 // kind_external: external[int32] = (double | int32) | 4663 // kind_external: external[int32] = (double | int32) |
| 4644 if (index == 0) { | 4664 if (index == 0) { |
| 4645 return is_external() ? Representation::External() | 4665 return is_external() ? Representation::External() |
| 4646 : Representation::Tagged(); | 4666 : Representation::Tagged(); |
| 4647 } else if (index == 1) { | 4667 } else if (index == 1) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4666 if (IsDoubleOrFloatElementsKind(elements_kind())) { | 4686 if (IsDoubleOrFloatElementsKind(elements_kind())) { |
| 4667 return Representation::Double(); | 4687 return Representation::Double(); |
| 4668 } | 4688 } |
| 4669 if (is_external()) { | 4689 if (is_external()) { |
| 4670 return Representation::Integer32(); | 4690 return Representation::Integer32(); |
| 4671 } | 4691 } |
| 4672 // For fast object elements kinds, don't assume anything. | 4692 // For fast object elements kinds, don't assume anything. |
| 4673 return Representation::None(); | 4693 return Representation::None(); |
| 4674 } | 4694 } |
| 4675 | 4695 |
| 4676 HValue* elements() { return OperandAt(0); } | |
| 4677 HValue* key() { return OperandAt(1); } | |
| 4678 HValue* value() { return OperandAt(2); } | 4696 HValue* value() { return OperandAt(2); } |
| 4679 bool value_is_smi() const { | 4697 bool value_is_smi() const { |
| 4680 return IsFastSmiElementsKind(elements_kind_); | 4698 return IsFastSmiElementsKind(elements_kind_); |
| 4681 } | 4699 } |
| 4682 ElementsKind elements_kind() const { return elements_kind_; } | 4700 ElementsKind elements_kind() const { return elements_kind_; } |
| 4701 ElementsKind GetElementsKind() { return elements_kind(); } |
| 4683 uint32_t index_offset() { return index_offset_; } | 4702 uint32_t index_offset() { return index_offset_; } |
| 4684 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4703 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |
| 4685 HValue* GetKey() { return key(); } | |
| 4686 void SetKey(HValue* key) { SetOperandAt(1, key); } | |
| 4687 bool IsDehoisted() { return is_dehoisted_; } | 4704 bool IsDehoisted() { return is_dehoisted_; } |
| 4688 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 4705 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
| 4689 | 4706 |
| 4690 bool NeedsWriteBarrier() { | 4707 bool NeedsWriteBarrier() { |
| 4691 if (value_is_smi()) { | 4708 if (value_is_smi()) { |
| 4692 return false; | 4709 return false; |
| 4693 } else { | 4710 } else { |
| 4694 return StoringValueNeedsWriteBarrier(value()); | 4711 return StoringValueNeedsWriteBarrier(value()); |
| 4695 } | 4712 } |
| 4696 } | 4713 } |
| 4697 | 4714 |
| 4698 bool NeedsCanonicalization(); | 4715 bool NeedsCanonicalization(); |
| 4699 | |
| 4700 virtual void PrintDataTo(StringStream* stream); | 4716 virtual void PrintDataTo(StringStream* stream); |
| 4701 | 4717 |
| 4702 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) | 4718 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
| 4703 | 4719 |
| 4704 private: | 4720 private: |
| 4705 ElementsKind elements_kind_; | 4721 ElementsKind elements_kind_; |
| 4706 uint32_t index_offset_; | 4722 uint32_t index_offset_; |
| 4707 bool is_dehoisted_; | 4723 bool is_dehoisted_; |
| 4708 }; | 4724 }; |
| 4709 | 4725 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 4740 | 4756 |
| 4741 private: | 4757 private: |
| 4742 StrictModeFlag strict_mode_flag_; | 4758 StrictModeFlag strict_mode_flag_; |
| 4743 }; | 4759 }; |
| 4744 | 4760 |
| 4745 | 4761 |
| 4746 class HTransitionElementsKind: public HTemplateInstruction<1> { | 4762 class HTransitionElementsKind: public HTemplateInstruction<1> { |
| 4747 public: | 4763 public: |
| 4748 HTransitionElementsKind(HValue* object, | 4764 HTransitionElementsKind(HValue* object, |
| 4749 Handle<Map> original_map, | 4765 Handle<Map> original_map, |
| 4750 Handle<Map> transitioned_map) | 4766 Handle<Map> transitioned_map, |
| 4751 : original_map_(original_map), | 4767 Isolate* isolate, |
| 4752 transitioned_map_(transitioned_map) { | 4768 bool calculatePessimisticHoleyAndFamily = true); |
| 4753 SetOperandAt(0, object); | |
| 4754 SetFlag(kUseGVN); | |
| 4755 SetGVNFlag(kChangesElementsKind); | |
| 4756 if (original_map->has_fast_double_elements()) { | |
| 4757 SetGVNFlag(kChangesElementsPointer); | |
| 4758 SetGVNFlag(kChangesNewSpacePromotion); | |
| 4759 } | |
| 4760 if (transitioned_map->has_fast_double_elements()) { | |
| 4761 SetGVNFlag(kChangesElementsPointer); | |
| 4762 SetGVNFlag(kChangesNewSpacePromotion); | |
| 4763 } | |
| 4764 set_representation(Representation::Tagged()); | |
| 4765 } | |
| 4766 | 4769 |
| 4767 virtual Representation RequiredInputRepresentation(int index) { | 4770 virtual Representation RequiredInputRepresentation(int index) { |
| 4768 return Representation::Tagged(); | 4771 return Representation::Tagged(); |
| 4769 } | 4772 } |
| 4770 | 4773 |
| 4771 HValue* object() { return OperandAt(0); } | 4774 HValue* object() { return OperandAt(0); } |
| 4772 Handle<Map> original_map() { return original_map_; } | 4775 |
| 4773 Handle<Map> transitioned_map() { return transitioned_map_; } | 4776 Handle<Map> original_map() const { return original_map_; } |
| 4777 Handle<Map> transitioned_map() const { return transitioned_map_; } |
| 4778 Handle<Map> family() const { return family_; } |
| 4779 Handle<Map> pessimistic_holey() const { return pessimistic_holey_; } |
| 4780 |
| 4781 bool is_special_case() const { return special_case_; } |
| 4782 void set_special_case() { special_case_ = true; } |
| 4774 | 4783 |
| 4775 virtual void PrintDataTo(StringStream* stream); | 4784 virtual void PrintDataTo(StringStream* stream); |
| 4776 | 4785 |
| 4777 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) | 4786 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) |
| 4778 | 4787 |
| 4779 protected: | 4788 protected: |
| 4780 virtual bool DataEquals(HValue* other) { | 4789 virtual bool DataEquals(HValue* other) { |
| 4781 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); | 4790 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); |
| 4782 return original_map_.is_identical_to(instr->original_map()) && | 4791 return original_map_.is_identical_to(instr->original_map()) && |
| 4783 transitioned_map_.is_identical_to(instr->transitioned_map()); | 4792 transitioned_map_.is_identical_to(instr->transitioned_map()); |
| 4784 } | 4793 } |
| 4785 | 4794 |
| 4786 private: | 4795 private: |
| 4787 Handle<Map> original_map_; | 4796 Handle<Map> original_map_; |
| 4788 Handle<Map> transitioned_map_; | 4797 Handle<Map> transitioned_map_; |
| 4798 Handle<Map> pessimistic_holey_; |
| 4799 Handle<Map> family_; |
| 4800 bool special_case_; |
| 4789 }; | 4801 }; |
| 4790 | 4802 |
| 4791 | 4803 |
| 4792 class HStringAdd: public HBinaryOperation { | 4804 class HStringAdd: public HBinaryOperation { |
| 4793 public: | 4805 public: |
| 4794 HStringAdd(HValue* context, HValue* left, HValue* right) | 4806 HStringAdd(HValue* context, HValue* left, HValue* right) |
| 4795 : HBinaryOperation(context, left, right) { | 4807 : HBinaryOperation(context, left, right) { |
| 4796 set_representation(Representation::Tagged()); | 4808 set_representation(Representation::Tagged()); |
| 4797 SetFlag(kUseGVN); | 4809 SetFlag(kUseGVN); |
| 4798 SetGVNFlag(kDependsOnMaps); | 4810 SetGVNFlag(kDependsOnMaps); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4963 | 4975 |
| 4964 int literal_index_; | 4976 int literal_index_; |
| 4965 int depth_; | 4977 int depth_; |
| 4966 }; | 4978 }; |
| 4967 | 4979 |
| 4968 | 4980 |
| 4969 class HFastLiteral: public HMaterializedLiteral<1> { | 4981 class HFastLiteral: public HMaterializedLiteral<1> { |
| 4970 public: | 4982 public: |
| 4971 HFastLiteral(HValue* context, | 4983 HFastLiteral(HValue* context, |
| 4972 Handle<JSObject> boilerplate, | 4984 Handle<JSObject> boilerplate, |
| 4973 int total_size, | |
| 4974 int literal_index, | 4985 int literal_index, |
| 4975 int depth) | 4986 int depth) |
| 4976 : HMaterializedLiteral<1>(literal_index, depth), | 4987 : HMaterializedLiteral<1>(literal_index, depth), |
| 4977 boilerplate_(boilerplate), | 4988 boilerplate_(boilerplate) { |
| 4978 total_size_(total_size) { | 4989 transition_to_ = boilerplate->GetElementsKind(); |
| 4979 SetOperandAt(0, context); | 4990 SetOperandAt(0, context); |
| 4980 SetGVNFlag(kChangesNewSpacePromotion); | 4991 SetGVNFlag(kChangesNewSpacePromotion); |
| 4981 } | 4992 } |
| 4982 | 4993 |
| 4983 // Maximum depth and total number of elements and properties for literal | 4994 // Maximum depth and total number of elements and properties for literal |
| 4984 // graphs to be considered for fast deep-copying. | 4995 // graphs to be considered for fast deep-copying. |
| 4985 static const int kMaxLiteralDepth = 3; | 4996 static const int kMaxLiteralDepth = 3; |
| 4986 static const int kMaxLiteralProperties = 8; | 4997 static const int kMaxLiteralProperties = 8; |
| 4987 | 4998 |
| 4988 HValue* context() { return OperandAt(0); } | 4999 HValue* context() { return OperandAt(0); } |
| 4989 Handle<JSObject> boilerplate() const { return boilerplate_; } | 5000 Handle<JSObject> boilerplate() const { return boilerplate_; } |
| 4990 int total_size() const { return total_size_; } | |
| 4991 | 5001 |
| 4992 virtual Representation RequiredInputRepresentation(int index) { | 5002 virtual Representation RequiredInputRepresentation(int index) { |
| 4993 return Representation::Tagged(); | 5003 return Representation::Tagged(); |
| 4994 } | 5004 } |
| 4995 virtual HType CalculateInferredType(); | 5005 virtual HType CalculateInferredType(); |
| 4996 | 5006 |
| 5007 void SetTransitionTo(ElementsKind elements_kind) { |
| 5008 transition_to_ = elements_kind; |
| 5009 } |
| 5010 ElementsKind TransitionTo() { return transition_to_; } |
| 5011 bool TransitionRequested() { |
| 5012 return transition_to_ != boilerplate()->GetElementsKind(); |
| 5013 } |
| 5014 |
| 4997 DECLARE_CONCRETE_INSTRUCTION(FastLiteral) | 5015 DECLARE_CONCRETE_INSTRUCTION(FastLiteral) |
| 4998 | 5016 |
| 5017 static bool IsFastLiteral(Handle<JSObject> boilerplate, |
| 5018 int max_depth, |
| 5019 int* max_properties, |
| 5020 int* total_size); |
| 5021 |
| 5022 virtual void PrintDataTo(StringStream* stream); |
| 5023 |
| 4999 private: | 5024 private: |
| 5000 Handle<JSObject> boilerplate_; | 5025 Handle<JSObject> boilerplate_; |
| 5001 int total_size_; | 5026 ElementsKind transition_to_; |
| 5002 }; | 5027 }; |
| 5003 | 5028 |
| 5004 | 5029 |
| 5005 class HArrayLiteral: public HMaterializedLiteral<1> { | 5030 class HArrayLiteral: public HMaterializedLiteral<1> { |
| 5006 public: | 5031 public: |
| 5007 HArrayLiteral(HValue* context, | 5032 HArrayLiteral(HValue* context, |
| 5008 Handle<HeapObject> boilerplate_object, | 5033 Handle<HeapObject> boilerplate_object, |
| 5009 int length, | 5034 int length, |
| 5010 int literal_index, | 5035 int literal_index, |
| 5011 int depth) | 5036 int depth) |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5430 virtual bool IsDeletable() const { return true; } | 5455 virtual bool IsDeletable() const { return true; } |
| 5431 }; | 5456 }; |
| 5432 | 5457 |
| 5433 | 5458 |
| 5434 #undef DECLARE_INSTRUCTION | 5459 #undef DECLARE_INSTRUCTION |
| 5435 #undef DECLARE_CONCRETE_INSTRUCTION | 5460 #undef DECLARE_CONCRETE_INSTRUCTION |
| 5436 | 5461 |
| 5437 } } // namespace v8::internal | 5462 } } // namespace v8::internal |
| 5438 | 5463 |
| 5439 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5464 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |