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

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

Issue 300893003: Refactor HType to get rid of various hacks. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix compilation. Created 6 years, 6 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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_
6 #define V8_HYDROGEN_INSTRUCTIONS_H_ 6 #define V8_HYDROGEN_INSTRUCTIONS_H_
7 7
8 #include "v8.h" 8 #include "v8.h"
9 9
10 #include "allocation.h" 10 #include "allocation.h"
11 #include "code-stubs.h" 11 #include "code-stubs.h"
12 #include "conversions.h" 12 #include "conversions.h"
13 #include "data-flow.h" 13 #include "data-flow.h"
14 #include "deoptimizer.h" 14 #include "deoptimizer.h"
15 #include "hydrogen-types.h"
15 #include "small-pointer-list.h" 16 #include "small-pointer-list.h"
16 #include "string-stream.h" 17 #include "string-stream.h"
17 #include "unique.h" 18 #include "unique.h"
18 #include "utils.h" 19 #include "utils.h"
19 #include "zone.h" 20 #include "zone.h"
20 21
21 namespace v8 { 22 namespace v8 {
22 namespace internal { 23 namespace internal {
23 24
24 // Forward declarations. 25 // Forward declarations.
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 bool MulAndCheckOverflow(const Representation& r, Range* other); 276 bool MulAndCheckOverflow(const Representation& r, Range* other);
276 277
277 private: 278 private:
278 int32_t lower_; 279 int32_t lower_;
279 int32_t upper_; 280 int32_t upper_;
280 Range* next_; 281 Range* next_;
281 bool can_be_minus_zero_; 282 bool can_be_minus_zero_;
282 }; 283 };
283 284
284 285
285 class HType V8_FINAL {
286 public:
287 static HType None() { return HType(kNone); }
288 static HType Tagged() { return HType(kTagged); }
289 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
290 static HType TaggedNumber() { return HType(kTaggedNumber); }
291 static HType Smi() { return HType(kSmi); }
292 static HType HeapNumber() { return HType(kHeapNumber); }
293 static HType String() { return HType(kString); }
294 static HType Boolean() { return HType(kBoolean); }
295 static HType NonPrimitive() { return HType(kNonPrimitive); }
296 static HType JSArray() { return HType(kJSArray); }
297 static HType JSObject() { return HType(kJSObject); }
298
299 // Return the weakest (least precise) common type.
300 HType Combine(HType other) {
301 return HType(static_cast<Type>(type_ & other.type_));
302 }
303
304 bool Equals(const HType& other) const {
305 return type_ == other.type_;
306 }
307
308 bool IsSubtypeOf(const HType& other) {
309 return Combine(other).Equals(other);
310 }
311
312 bool IsTaggedPrimitive() const {
313 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
314 }
315
316 bool IsTaggedNumber() const {
317 return ((type_ & kTaggedNumber) == kTaggedNumber);
318 }
319
320 bool IsSmi() const {
321 return ((type_ & kSmi) == kSmi);
322 }
323
324 bool IsHeapNumber() const {
325 return ((type_ & kHeapNumber) == kHeapNumber);
326 }
327
328 bool IsString() const {
329 return ((type_ & kString) == kString);
330 }
331
332 bool IsNonString() const {
333 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() ||
334 IsBoolean() || IsJSArray();
335 }
336
337 bool IsBoolean() const {
338 return ((type_ & kBoolean) == kBoolean);
339 }
340
341 bool IsNonPrimitive() const {
342 return ((type_ & kNonPrimitive) == kNonPrimitive);
343 }
344
345 bool IsJSArray() const {
346 return ((type_ & kJSArray) == kJSArray);
347 }
348
349 bool IsJSObject() const {
350 return ((type_ & kJSObject) == kJSObject);
351 }
352
353 bool IsHeapObject() const {
354 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive();
355 }
356
357 bool ToStringOrToNumberCanBeObserved(Representation representation) {
358 switch (type_) {
359 case kTaggedPrimitive: // fallthru
360 case kTaggedNumber: // fallthru
361 case kSmi: // fallthru
362 case kHeapNumber: // fallthru
363 case kString: // fallthru
364 case kBoolean:
365 return false;
366 case kJSArray: // fallthru
367 case kJSObject:
368 return true;
369 case kTagged:
370 break;
371 }
372 return !representation.IsSmiOrInteger32() && !representation.IsDouble();
373 }
374
375 static HType TypeFromValue(Handle<Object> value);
376
377 const char* ToString();
378
379 private:
380 enum Type {
381 kNone = 0x0, // 0000 0000 0000 0000
382 kTagged = 0x1, // 0000 0000 0000 0001
383 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
384 kTaggedNumber = 0xd, // 0000 0000 0000 1101
385 kSmi = 0x1d, // 0000 0000 0001 1101
386 kHeapNumber = 0x2d, // 0000 0000 0010 1101
387 kString = 0x45, // 0000 0000 0100 0101
388 kBoolean = 0x85, // 0000 0000 1000 0101
389 kNonPrimitive = 0x101, // 0000 0001 0000 0001
390 kJSObject = 0x301, // 0000 0011 0000 0001
391 kJSArray = 0x701 // 0000 0111 0000 0001
392 };
393
394 // Make sure type fits in int16.
395 STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte)));
396
397 explicit HType(Type t) : type_(t) { }
398
399 int16_t type_;
400 };
401
402
403 class HUseListNode: public ZoneObject { 286 class HUseListNode: public ZoneObject {
404 public: 287 public:
405 HUseListNode(HValue* value, int index, HUseListNode* tail) 288 HUseListNode(HValue* value, int index, HUseListNode* tail)
406 : tail_(tail), value_(value), index_(index) { 289 : tail_(tail), value_(value), index_(index) {
407 } 290 }
408 291
409 HUseListNode* tail(); 292 HUseListNode* tail();
410 HValue* value() const { return value_; } 293 HValue* value() const { return value_; }
411 int index() const { return index_; } 294 int index() const { return index_; }
412 295
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 } 603 }
721 return r; 604 return r;
722 } 605 }
723 606
724 HType type() const { return type_; } 607 HType type() const { return type_; }
725 void set_type(HType new_type) { 608 void set_type(HType new_type) {
726 ASSERT(new_type.IsSubtypeOf(type_)); 609 ASSERT(new_type.IsSubtypeOf(type_));
727 type_ = new_type; 610 type_ = new_type;
728 } 611 }
729 612
730 bool IsHeapObject() {
731 return representation_.IsHeapObject() || type_.IsHeapObject();
732 }
733
734 // There are HInstructions that do not really change a value, they 613 // There are HInstructions that do not really change a value, they
735 // only add pieces of information to it (like bounds checks, map checks, 614 // only add pieces of information to it (like bounds checks, map checks,
736 // smi checks...). 615 // smi checks...).
737 // We call these instructions "informative definitions", or "iDef". 616 // We call these instructions "informative definitions", or "iDef".
738 // One of the iDef operands is special because it is the value that is 617 // One of the iDef operands is special because it is the value that is
739 // "transferred" to the output, we call it the "redefined operand". 618 // "transferred" to the output, we call it the "redefined operand".
740 // If an HValue is an iDef it must override RedefinedOperandIndex() so that 619 // If an HValue is an iDef it must override RedefinedOperandIndex() so that
741 // it does not return kNoRedefinedOperand; 620 // it does not return kNoRedefinedOperand;
742 static const int kNoRedefinedOperand = -1; 621 static const int kNoRedefinedOperand = -1;
743 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } 622 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 if (RedefinedOperand() != NULL) { 805 if (RedefinedOperand() != NULL) {
927 return RedefinedOperand()->TryDecompose(decomposition); 806 return RedefinedOperand()->TryDecompose(decomposition);
928 } else { 807 } else {
929 return false; 808 return false;
930 } 809 }
931 } 810 }
932 811
933 // Returns true conservatively if the program might be able to observe a 812 // Returns true conservatively if the program might be able to observe a
934 // ToString() operation on this value. 813 // ToString() operation on this value.
935 bool ToStringCanBeObserved() const { 814 bool ToStringCanBeObserved() const {
936 return type().ToStringOrToNumberCanBeObserved(representation()); 815 return ToStringOrToNumberCanBeObserved();
937 } 816 }
938 817
939 // Returns true conservatively if the program might be able to observe a 818 // Returns true conservatively if the program might be able to observe a
940 // ToNumber() operation on this value. 819 // ToNumber() operation on this value.
941 bool ToNumberCanBeObserved() const { 820 bool ToNumberCanBeObserved() const {
942 return type().ToStringOrToNumberCanBeObserved(representation()); 821 return ToStringOrToNumberCanBeObserved();
943 } 822 }
944 823
945 MinusZeroMode GetMinusZeroMode() { 824 MinusZeroMode GetMinusZeroMode() {
946 return CheckFlag(kBailoutOnMinusZero) 825 return CheckFlag(kBailoutOnMinusZero)
947 ? FAIL_ON_MINUS_ZERO : TREAT_MINUS_ZERO_AS_ZERO; 826 ? FAIL_ON_MINUS_ZERO : TREAT_MINUS_ZERO_AS_ZERO;
948 } 827 }
949 828
950 protected: 829 protected:
951 // This function must be overridden for instructions with flag kUseGVN, to 830 // This function must be overridden for instructions with flag kUseGVN, to
952 // compare the non-Operand parts of the instruction. 831 // compare the non-Operand parts of the instruction.
953 virtual bool DataEquals(HValue* other) { 832 virtual bool DataEquals(HValue* other) {
954 UNREACHABLE(); 833 UNREACHABLE();
955 return false; 834 return false;
956 } 835 }
957 836
837 bool ToStringOrToNumberCanBeObserved() const {
838 if (type().IsTaggedPrimitive()) return false;
839 if (type().IsJSObject()) return true;
840 return !representation().IsSmiOrInteger32() && !representation().IsDouble();
841 }
842
958 virtual Representation RepresentationFromInputs() { 843 virtual Representation RepresentationFromInputs() {
959 return representation(); 844 return representation();
960 } 845 }
961 virtual Representation RepresentationFromUses(); 846 virtual Representation RepresentationFromUses();
962 Representation RepresentationFromUseRequirements(); 847 Representation RepresentationFromUseRequirements();
963 bool HasNonSmiUse(); 848 bool HasNonSmiUse();
964 virtual void UpdateRepresentation(Representation new_rep, 849 virtual void UpdateRepresentation(Representation new_rep,
965 HInferRepresentationPhase* h_infer, 850 HInferRepresentationPhase* h_infer,
966 const char* reason); 851 const char* reason);
967 void AddDependantsToWorklist(HInferRepresentationPhase* h_infer); 852 void AddDependantsToWorklist(HInferRepresentationPhase* h_infer);
(...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after
2832 is_stability_check_ = true; 2717 is_stability_check_ = true;
2833 ClearChangesFlag(kNewSpacePromotion); 2718 ClearChangesFlag(kNewSpacePromotion);
2834 ClearDependsOnFlag(kElementsKind); 2719 ClearDependsOnFlag(kElementsKind);
2835 ClearDependsOnFlag(kMaps); 2720 ClearDependsOnFlag(kMaps);
2836 } 2721 }
2837 2722
2838 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } 2723 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
2839 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2724 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2840 return Representation::Tagged(); 2725 return Representation::Tagged();
2841 } 2726 }
2727
2728 virtual HType CalculateInferredType() V8_OVERRIDE {
2729 if (value()->type().IsHeapObject()) return value()->type();
2730 return HType::HeapObject();
2731 }
2732
2842 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2733 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2843 2734
2844 HValue* value() { return OperandAt(0); } 2735 HValue* value() const { return OperandAt(0); }
2845 HValue* typecheck() { return OperandAt(1); } 2736 HValue* typecheck() const { return OperandAt(1); }
2846 2737
2847 const UniqueSet<Map>* maps() const { return maps_; } 2738 const UniqueSet<Map>* maps() const { return maps_; }
2848 void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; } 2739 void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }
2849 2740
2850 bool maps_are_stable() const { return maps_are_stable_; } 2741 bool maps_are_stable() const { return maps_are_stable_; }
2851 2742
2852 bool HasMigrationTarget() const { return has_migration_target_; } 2743 bool HasMigrationTarget() const { return has_migration_target_; }
2853 2744
2854 virtual HValue* Canonicalize() V8_OVERRIDE; 2745 virtual HValue* Canonicalize() V8_OVERRIDE;
2855 2746
(...skipping 18 matching lines...) Expand all
2874 2765
2875 protected: 2766 protected:
2876 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 2767 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
2877 return this->maps()->Equals(HCheckMaps::cast(other)->maps()); 2768 return this->maps()->Equals(HCheckMaps::cast(other)->maps());
2878 } 2769 }
2879 2770
2880 virtual int RedefinedOperandIndex() { return 0; } 2771 virtual int RedefinedOperandIndex() { return 0; }
2881 2772
2882 private: 2773 private:
2883 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable) 2774 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable)
2884 : HTemplateInstruction<2>(value->type()), maps_(maps), 2775 : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps),
2885 has_migration_target_(false), is_stability_check_(false), 2776 has_migration_target_(false), is_stability_check_(false),
2886 maps_are_stable_(maps_are_stable) { 2777 maps_are_stable_(maps_are_stable) {
2887 ASSERT_NE(0, maps->size()); 2778 ASSERT_NE(0, maps->size());
2888 SetOperandAt(0, value); 2779 SetOperandAt(0, value);
2889 // Use the object value for the dependency. 2780 // Use the object value for the dependency.
2890 SetOperandAt(1, value); 2781 SetOperandAt(1, value);
2891 set_representation(Representation::Tagged()); 2782 set_representation(Representation::Tagged());
2892 SetFlag(kUseGVN); 2783 SetFlag(kUseGVN);
2893 SetDependsOnFlag(kMaps); 2784 SetDependsOnFlag(kMaps);
2894 SetDependsOnFlag(kElementsKind); 2785 SetDependsOnFlag(kElementsKind);
2895 } 2786 }
2896 2787
2897 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck) 2788 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
2898 : HTemplateInstruction<2>(value->type()), maps_(maps), 2789 : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps),
2899 has_migration_target_(false), is_stability_check_(false), 2790 has_migration_target_(false), is_stability_check_(false),
2900 maps_are_stable_(true) { 2791 maps_are_stable_(true) {
2901 ASSERT_NE(0, maps->size()); 2792 ASSERT_NE(0, maps->size());
2902 SetOperandAt(0, value); 2793 SetOperandAt(0, value);
2903 // Use the object value for the dependency if NULL is passed. 2794 // Use the object value for the dependency if NULL is passed.
2904 SetOperandAt(1, typecheck ? typecheck : value); 2795 SetOperandAt(1, typecheck ? typecheck : value);
2905 set_representation(Representation::Tagged()); 2796 set_representation(Representation::Tagged());
2906 SetFlag(kUseGVN); 2797 SetFlag(kUseGVN);
2907 SetDependsOnFlag(kMaps); 2798 SetDependsOnFlag(kMaps);
2908 SetDependsOnFlag(kElementsKind); 2799 SetDependsOnFlag(kElementsKind);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 }; 2883 };
2993 2884
2994 DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check); 2885 DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check);
2995 2886
2996 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2887 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2997 2888
2998 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2889 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2999 return Representation::Tagged(); 2890 return Representation::Tagged();
3000 } 2891 }
3001 2892
2893 virtual HType CalculateInferredType() V8_OVERRIDE {
2894 switch (check_) {
2895 case IS_SPEC_OBJECT: return HType::JSObject();
2896 case IS_JS_ARRAY: return HType::JSArray();
2897 case IS_STRING: return HType::String();
2898 case IS_INTERNALIZED_STRING: return HType::String();
2899 }
2900 UNREACHABLE();
2901 return HType::Tagged();
2902 }
2903
3002 virtual HValue* Canonicalize() V8_OVERRIDE; 2904 virtual HValue* Canonicalize() V8_OVERRIDE;
3003 2905
3004 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; } 2906 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
3005 void GetCheckInterval(InstanceType* first, InstanceType* last); 2907 void GetCheckInterval(InstanceType* first, InstanceType* last);
3006 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag); 2908 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
3007 2909
3008 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType) 2910 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
3009 2911
3010 protected: 2912 protected:
3011 // TODO(ager): It could be nice to allow the ommision of instance 2913 // TODO(ager): It could be nice to allow the ommision of instance
3012 // type checks if we have already performed an instance type check 2914 // type checks if we have already performed an instance type check
3013 // with a larger range. 2915 // with a larger range.
3014 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 2916 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
3015 HCheckInstanceType* b = HCheckInstanceType::cast(other); 2917 HCheckInstanceType* b = HCheckInstanceType::cast(other);
3016 return check_ == b->check_; 2918 return check_ == b->check_;
3017 } 2919 }
3018 2920
3019 virtual int RedefinedOperandIndex() { return 0; } 2921 virtual int RedefinedOperandIndex() { return 0; }
3020 2922
3021 private: 2923 private:
3022 const char* GetCheckName(); 2924 const char* GetCheckName();
3023 2925
3024 HCheckInstanceType(HValue* value, Check check) 2926 HCheckInstanceType(HValue* value, Check check)
3025 : HUnaryOperation(value), check_(check) { 2927 : HUnaryOperation(value, HType::HeapObject()), check_(check) {
3026 set_representation(Representation::Tagged()); 2928 set_representation(Representation::Tagged());
3027 SetFlag(kUseGVN); 2929 SetFlag(kUseGVN);
3028 } 2930 }
3029 2931
3030 const Check check_; 2932 const Check check_;
3031 }; 2933 };
3032 2934
3033 2935
3034 class HCheckSmi V8_FINAL : public HUnaryOperation { 2936 class HCheckSmi V8_FINAL : public HUnaryOperation {
3035 public: 2937 public:
(...skipping 26 matching lines...) Expand all
3062 2964
3063 class HCheckHeapObject V8_FINAL : public HUnaryOperation { 2965 class HCheckHeapObject V8_FINAL : public HUnaryOperation {
3064 public: 2966 public:
3065 DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); 2967 DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*);
3066 2968
3067 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } 2969 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
3068 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2970 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
3069 return Representation::Tagged(); 2971 return Representation::Tagged();
3070 } 2972 }
3071 2973
2974 virtual HType CalculateInferredType() V8_OVERRIDE {
2975 if (value()->type().IsHeapObject()) return value()->type();
2976 return HType::HeapObject();
2977 }
2978
3072 #ifdef DEBUG 2979 #ifdef DEBUG
3073 virtual void Verify() V8_OVERRIDE; 2980 virtual void Verify() V8_OVERRIDE;
3074 #endif 2981 #endif
3075 2982
3076 virtual HValue* Canonicalize() V8_OVERRIDE { 2983 virtual HValue* Canonicalize() V8_OVERRIDE {
3077 return value()->type().IsHeapObject() ? NULL : this; 2984 return value()->type().IsHeapObject() ? NULL : this;
3078 } 2985 }
3079 2986
3080 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) 2987 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject)
3081 2988
3082 protected: 2989 protected:
3083 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 2990 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
3084 2991
3085 private: 2992 private:
3086 explicit HCheckHeapObject(HValue* value) 2993 explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) {
3087 : HUnaryOperation(value, HType::NonPrimitive()) {
3088 set_representation(Representation::Tagged()); 2994 set_representation(Representation::Tagged());
3089 SetFlag(kUseGVN); 2995 SetFlag(kUseGVN);
3090 } 2996 }
3091 }; 2997 };
3092 2998
3093 2999
3094 class InductionVariableData; 3000 class InductionVariableData;
3095 3001
3096 3002
3097 struct InductionVariableLimitUpdate { 3003 struct InductionVariableLimitUpdate {
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
3559 return instruction->Prepend(HConstant::New( 3465 return instruction->Prepend(HConstant::New(
3560 zone, context, value, representation)); 3466 zone, context, value, representation));
3561 } 3467 }
3562 3468
3563 static HConstant* CreateAndInsertBefore(Zone* zone, 3469 static HConstant* CreateAndInsertBefore(Zone* zone,
3564 Unique<Map> map, 3470 Unique<Map> map,
3565 bool map_is_stable, 3471 bool map_is_stable,
3566 HInstruction* instruction) { 3472 HInstruction* instruction) {
3567 return instruction->Prepend(new(zone) HConstant( 3473 return instruction->Prepend(new(zone) HConstant(
3568 map, Unique<Map>(Handle<Map>::null()), map_is_stable, 3474 map, Unique<Map>(Handle<Map>::null()), map_is_stable,
3569 Representation::Tagged(), HType::Tagged(), true, 3475 Representation::Tagged(), HType::HeapObject(), true,
3570 false, false, MAP_TYPE)); 3476 false, false, MAP_TYPE));
3571 } 3477 }
3572 3478
3573 static HConstant* CreateAndInsertAfter(Zone* zone, 3479 static HConstant* CreateAndInsertAfter(Zone* zone,
3574 Unique<Map> map, 3480 Unique<Map> map,
3575 bool map_is_stable, 3481 bool map_is_stable,
3576 HInstruction* instruction) { 3482 HInstruction* instruction) {
3577 return instruction->Append(new(zone) HConstant( 3483 return instruction->Append(new(zone) HConstant(
3578 map, Unique<Map>(Handle<Map>::null()), map_is_stable, 3484 map, Unique<Map>(Handle<Map>::null()), map_is_stable,
3579 Representation::Tagged(), HType::Tagged(), true, 3485 Representation::Tagged(), HType::HeapObject(), true,
3580 false, false, MAP_TYPE)); 3486 false, false, MAP_TYPE));
3581 } 3487 }
3582 3488
3583 Handle<Object> handle(Isolate* isolate) { 3489 Handle<Object> handle(Isolate* isolate) {
3584 if (object_.handle().is_null()) { 3490 if (object_.handle().is_null()) {
3585 // Default arguments to is_not_in_new_space depend on this heap number 3491 // Default arguments to is_not_in_new_space depend on this heap number
3586 // to be tenured so that it's guaranteed not to be located in new space. 3492 // to be tenured so that it's guaranteed not to be located in new space.
3587 object_ = Unique<Object>::CreateUninitialized( 3493 object_ = Unique<Object>::CreateUninitialized(
3588 isolate->factory()->NewNumber(double_value_, TENURED)); 3494 isolate->factory()->NewNumber(double_value_, TENURED));
3589 } 3495 }
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
4180 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 4086 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
4181 4087
4182 virtual int RedefinedOperandIndex() V8_OVERRIDE { return 0; } 4088 virtual int RedefinedOperandIndex() V8_OVERRIDE { return 0; }
4183 virtual bool IsPurelyInformativeDefinition() V8_OVERRIDE { return true; } 4089 virtual bool IsPurelyInformativeDefinition() V8_OVERRIDE { return true; }
4184 }; 4090 };
4185 4091
4186 4092
4187 class HBitwiseBinaryOperation : public HBinaryOperation { 4093 class HBitwiseBinaryOperation : public HBinaryOperation {
4188 public: 4094 public:
4189 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, 4095 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
4190 HType type = HType::Tagged()) 4096 HType type = HType::TaggedNumber())
4191 : HBinaryOperation(context, left, right, type) { 4097 : HBinaryOperation(context, left, right, type) {
4192 SetFlag(kFlexibleRepresentation); 4098 SetFlag(kFlexibleRepresentation);
4193 SetFlag(kTruncatingToInt32); 4099 SetFlag(kTruncatingToInt32);
4194 SetFlag(kAllowUndefinedAsNaN); 4100 SetFlag(kAllowUndefinedAsNaN);
4195 SetAllSideEffects(); 4101 SetAllSideEffects();
4196 } 4102 }
4197 4103
4198 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { 4104 virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
4199 if (to.IsTagged() && 4105 if (to.IsTagged() &&
4200 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { 4106 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
5133 return op() == HBitwise::cast(other)->op(); 5039 return op() == HBitwise::cast(other)->op();
5134 } 5040 }
5135 5041
5136 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; 5042 virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
5137 5043
5138 private: 5044 private:
5139 HBitwise(HValue* context, 5045 HBitwise(HValue* context,
5140 Token::Value op, 5046 Token::Value op,
5141 HValue* left, 5047 HValue* left,
5142 HValue* right) 5048 HValue* right)
5143 : HBitwiseBinaryOperation(context, left, right, HType::TaggedNumber()), 5049 : HBitwiseBinaryOperation(context, left, right),
5144 op_(op) { 5050 op_(op) {
5145 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); 5051 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
5146 // BIT_AND with a smi-range positive value will always unset the 5052 // BIT_AND with a smi-range positive value will always unset the
5147 // entire sign-extension of the smi-sign. 5053 // entire sign-extension of the smi-sign.
5148 if (op == Token::BIT_AND && 5054 if (op == Token::BIT_AND &&
5149 ((left->IsConstant() && 5055 ((left->IsConstant() &&
5150 left->representation().IsSmi() && 5056 left->representation().IsSmi() &&
5151 HConstant::cast(left)->Integer32Value() >= 0) || 5057 HConstant::cast(left)->Integer32Value() >= 0) ||
5152 (right->IsConstant() && 5058 (right->IsConstant() &&
5153 right->representation().IsSmi() && 5059 right->representation().IsSmi() &&
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
5712 } 5618 }
5713 }; 5619 };
5714 5620
5715 5621
5716 class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<2> { 5622 class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<2> {
5717 public: 5623 public:
5718 static HInnerAllocatedObject* New(Zone* zone, 5624 static HInnerAllocatedObject* New(Zone* zone,
5719 HValue* context, 5625 HValue* context,
5720 HValue* value, 5626 HValue* value,
5721 HValue* offset, 5627 HValue* offset,
5722 HType type = HType::Tagged()) { 5628 HType type) {
5723 return new(zone) HInnerAllocatedObject(value, offset, type); 5629 return new(zone) HInnerAllocatedObject(value, offset, type);
5724 } 5630 }
5725 5631
5726 HValue* base_object() { return OperandAt(0); } 5632 HValue* base_object() { return OperandAt(0); }
5727 HValue* offset() { return OperandAt(1); } 5633 HValue* offset() { return OperandAt(1); }
5728 5634
5729 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 5635 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
5730 return index == 0 ? Representation::Tagged() : Representation::Integer32(); 5636 return index == 0 ? Representation::Tagged() : Representation::Integer32();
5731 } 5637 }
5732 5638
5733 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 5639 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
5734 5640
5735 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) 5641 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
5736 5642
5737 private: 5643 private:
5738 HInnerAllocatedObject(HValue* value, 5644 HInnerAllocatedObject(HValue* value,
5739 HValue* offset, 5645 HValue* offset,
5740 HType type = HType::Tagged()) 5646 HType type) : HTemplateInstruction<2>(type) {
5741 : HTemplateInstruction<2>(type) {
5742 ASSERT(value->IsAllocate()); 5647 ASSERT(value->IsAllocate());
5648 ASSERT(type.IsHeapObject());
5743 SetOperandAt(0, value); 5649 SetOperandAt(0, value);
5744 SetOperandAt(1, offset); 5650 SetOperandAt(1, offset);
5745 set_type(type);
5746 set_representation(Representation::Tagged()); 5651 set_representation(Representation::Tagged());
5747 } 5652 }
5748 }; 5653 };
5749 5654
5750 5655
5751 inline bool StoringValueNeedsWriteBarrier(HValue* value) { 5656 inline bool StoringValueNeedsWriteBarrier(HValue* value) {
5752 return !value->type().IsBoolean() 5657 return !value->type().IsSmi()
5753 && !value->type().IsSmi() 5658 && !value->type().IsNull()
5659 && !value->type().IsBoolean()
5660 && !value->type().IsUndefined()
5754 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); 5661 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
5755 } 5662 }
5756 5663
5757 5664
5758 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, 5665 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
5759 HValue* value, 5666 HValue* value,
5760 HValue* dominator) { 5667 HValue* dominator) {
5761 while (object->IsInnerAllocatedObject()) { 5668 while (object->IsInnerAllocatedObject()) {
5762 object = HInnerAllocatedObject::cast(object)->base_object(); 5669 object = HInnerAllocatedObject::cast(object)->base_object();
5763 } 5670 }
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
6364 if (SmiValuesAre32Bits()) { 6271 if (SmiValuesAre32Bits()) {
6365 set_representation(Representation::Integer32()); 6272 set_representation(Representation::Integer32());
6366 } else { 6273 } else {
6367 set_representation(representation); 6274 set_representation(representation);
6368 } 6275 }
6369 } else if (representation.IsDouble() || 6276 } else if (representation.IsDouble() ||
6370 representation.IsExternal() || 6277 representation.IsExternal() ||
6371 representation.IsInteger32()) { 6278 representation.IsInteger32()) {
6372 set_representation(representation); 6279 set_representation(representation);
6373 } else if (representation.IsHeapObject()) { 6280 } else if (representation.IsHeapObject()) {
6374 // TODO(bmeurer): This is probably broken. What we actually want to to 6281 set_type(HType::HeapObject());
6375 // instead is set_representation(Representation::HeapObject()).
6376 set_type(HType::NonPrimitive());
6377 set_representation(Representation::Tagged()); 6282 set_representation(Representation::Tagged());
6378 } else { 6283 } else {
6379 set_representation(Representation::Tagged()); 6284 set_representation(Representation::Tagged());
6380 } 6285 }
6381 access.SetGVNFlags(this, LOAD); 6286 access.SetGVNFlags(this, LOAD);
6382 } 6287 }
6383 6288
6384 HLoadNamedField(HValue* object, 6289 HLoadNamedField(HValue* object,
6385 HValue* dependency, 6290 HValue* dependency,
6386 HObjectAccess access, 6291 HObjectAccess access,
6387 const UniqueSet<Map>* maps, 6292 const UniqueSet<Map>* maps,
6388 HType type) 6293 HType type)
6389 : HTemplateInstruction<2>(type), access_(access), maps_(maps) { 6294 : HTemplateInstruction<2>(type), access_(access), maps_(maps) {
6390 ASSERT_NOT_NULL(maps); 6295 ASSERT_NOT_NULL(maps);
6391 ASSERT_NE(0, maps->size()); 6296 ASSERT_NE(0, maps->size());
6392 6297
6393 ASSERT_NOT_NULL(object); 6298 ASSERT_NOT_NULL(object);
6394 SetOperandAt(0, object); 6299 SetOperandAt(0, object);
6395 SetOperandAt(1, dependency ? dependency : object); 6300 SetOperandAt(1, dependency ? dependency : object);
6396 6301
6397 ASSERT(access.representation().IsHeapObject()); 6302 ASSERT(access.representation().IsHeapObject());
6398 // TODO(bmeurer): This is probably broken. What we actually want to to 6303 ASSERT(type.IsHeapObject());
6399 // instead is set_representation(Representation::HeapObject()).
6400 if (!type.IsHeapObject()) set_type(HType::NonPrimitive());
6401 set_representation(Representation::Tagged()); 6304 set_representation(Representation::Tagged());
6402 6305
6403 access.SetGVNFlags(this, LOAD); 6306 access.SetGVNFlags(this, LOAD);
6404 } 6307 }
6405 6308
6406 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 6309 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
6407 6310
6408 HObjectAccess access_; 6311 HObjectAccess access_;
6409 const UniqueSet<Map>* maps_; 6312 const UniqueSet<Map>* maps_;
6410 }; 6313 };
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
6806 new_space_dominator()); 6709 new_space_dominator());
6807 } 6710 }
6808 6711
6809 bool NeedsWriteBarrierForMap() { 6712 bool NeedsWriteBarrierForMap() {
6810 return ReceiverObjectNeedsWriteBarrier(object(), transition(), 6713 return ReceiverObjectNeedsWriteBarrier(object(), transition(),
6811 new_space_dominator()); 6714 new_space_dominator());
6812 } 6715 }
6813 6716
6814 SmiCheck SmiCheckForWriteBarrier() const { 6717 SmiCheck SmiCheckForWriteBarrier() const {
6815 if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK; 6718 if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK;
6816 if (value()->IsHeapObject()) return OMIT_SMI_CHECK; 6719 if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK;
6817 return INLINE_SMI_CHECK; 6720 return INLINE_SMI_CHECK;
6818 } 6721 }
6819 6722
6820 Representation field_representation() const { 6723 Representation field_representation() const {
6821 return access_.representation(); 6724 return access_.representation();
6822 } 6725 }
6823 6726
6824 void UpdateValue(HValue* value) { 6727 void UpdateValue(HValue* value) {
6825 SetOperandAt(1, value); 6728 SetOperandAt(1, value);
6826 } 6729 }
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
7666 public: 7569 public:
7667 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*); 7570 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*);
7668 7571
7669 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 7572 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
7670 return Representation::Tagged(); 7573 return Representation::Tagged();
7671 } 7574 }
7672 7575
7673 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 7576 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
7674 7577
7675 virtual HType CalculateInferredType() V8_OVERRIDE { 7578 virtual HType CalculateInferredType() V8_OVERRIDE {
7676 return HType::Tagged(); 7579 if (value()->type().IsHeapObject()) return value()->type();
7580 return HType::HeapObject();
7677 } 7581 }
7678 7582
7679 HValue* value() { return OperandAt(0); } 7583 HValue* value() const { return OperandAt(0); }
7680 HValue* map() { return OperandAt(1); } 7584 HValue* map() const { return OperandAt(1); }
7681 7585
7682 virtual HValue* Canonicalize() V8_OVERRIDE; 7586 virtual HValue* Canonicalize() V8_OVERRIDE;
7683 7587
7684 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue) 7588 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
7685 7589
7686 protected: 7590 protected:
7687 virtual int RedefinedOperandIndex() { return 0; } 7591 virtual int RedefinedOperandIndex() { return 0; }
7688 7592
7689 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 7593 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
7690 return true; 7594 return true;
7691 } 7595 }
7692 7596
7693 private: 7597 private:
7694 HCheckMapValue(HValue* value, 7598 HCheckMapValue(HValue* value, HValue* map)
7695 HValue* map) { 7599 : HTemplateInstruction<2>(HType::HeapObject()) {
7696 SetOperandAt(0, value); 7600 SetOperandAt(0, value);
7697 SetOperandAt(1, map); 7601 SetOperandAt(1, map);
7698 set_representation(Representation::Tagged()); 7602 set_representation(Representation::Tagged());
7699 SetFlag(kUseGVN); 7603 SetFlag(kUseGVN);
7700 SetDependsOnFlag(kMaps); 7604 SetDependsOnFlag(kMaps);
7701 SetDependsOnFlag(kElementsKind); 7605 SetDependsOnFlag(kElementsKind);
7702 } 7606 }
7703 }; 7607 };
7704 7608
7705 7609
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
7810 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7714 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7811 }; 7715 };
7812 7716
7813 7717
7814 #undef DECLARE_INSTRUCTION 7718 #undef DECLARE_INSTRUCTION
7815 #undef DECLARE_CONCRETE_INSTRUCTION 7719 #undef DECLARE_CONCRETE_INSTRUCTION
7816 7720
7817 } } // namespace v8::internal 7721 } } // namespace v8::internal
7818 7722
7819 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 7723 #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