Chromium Code Reviews| 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 21 matching lines...) Expand all Loading... | |
| 32 | 32 |
| 33 #include "allocation.h" | 33 #include "allocation.h" |
| 34 #include "code-stubs.h" | 34 #include "code-stubs.h" |
| 35 #include "data-flow.h" | 35 #include "data-flow.h" |
| 36 #include "small-pointer-list.h" | 36 #include "small-pointer-list.h" |
| 37 #include "string-stream.h" | 37 #include "string-stream.h" |
| 38 #include "v8conversions.h" | 38 #include "v8conversions.h" |
| 39 #include "v8utils.h" | 39 #include "v8utils.h" |
| 40 #include "zone.h" | 40 #include "zone.h" |
| 41 | 41 |
| 42 | |
| 42 namespace v8 { | 43 namespace v8 { |
| 43 namespace internal { | 44 namespace internal { |
| 44 | 45 |
| 45 // Forward declarations. | 46 // Forward declarations. |
| 46 class HBasicBlock; | 47 class HBasicBlock; |
| 47 class HEnvironment; | 48 class HEnvironment; |
| 48 class HInferRepresentation; | 49 class HInferRepresentation; |
| 49 class HInstruction; | 50 class HInstruction; |
| 50 class HLoopInformation; | 51 class HLoopInformation; |
| 51 class HValue; | 52 class HValue; |
| (...skipping 2991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3043 | 3044 |
| 3044 private: | 3045 private: |
| 3045 ZoneList<Handle<JSObject> > prototypes_; | 3046 ZoneList<Handle<JSObject> > prototypes_; |
| 3046 ZoneList<Handle<Map> > maps_; | 3047 ZoneList<Handle<Map> > maps_; |
| 3047 UniqueValueId first_prototype_unique_id_; | 3048 UniqueValueId first_prototype_unique_id_; |
| 3048 UniqueValueId last_prototype_unique_id_; | 3049 UniqueValueId last_prototype_unique_id_; |
| 3049 bool can_omit_prototype_maps_; | 3050 bool can_omit_prototype_maps_; |
| 3050 }; | 3051 }; |
| 3051 | 3052 |
| 3052 | 3053 |
| 3054 class InductionVariableData; | |
| 3055 | |
| 3056 | |
| 3057 struct InductionVariableLimitUpdate { | |
| 3058 InductionVariableData* updated_variable; | |
| 3059 HValue* limit; | |
| 3060 bool limit_is_upper; | |
| 3061 bool limit_is_included; | |
| 3062 | |
| 3063 InductionVariableLimitUpdate() | |
| 3064 : updated_variable(NULL), limit(NULL), | |
| 3065 limit_is_upper(false), limit_is_included(false) {} | |
| 3066 }; | |
| 3067 | |
| 3068 | |
| 3069 class HBoundsCheck; | |
| 3070 class HPhi; | |
| 3071 class HConstant; | |
| 3072 class HBitwise; | |
| 3073 | |
| 3074 | |
| 3075 class InductionVariableData : public ZoneObject { | |
| 3076 public: | |
| 3077 class InductionVariableCheck : public ZoneObject { | |
| 3078 public: | |
| 3079 HBoundsCheck* check() { return check_; } | |
| 3080 InductionVariableCheck* next() { return next_; } | |
| 3081 bool HasUpperLimit() { return upper_limit_ >= 0; } | |
| 3082 int32_t upper_limit() { | |
| 3083 ASSERT(HasUpperLimit()); | |
| 3084 return upper_limit_; | |
| 3085 } | |
| 3086 void set_upper_limit(int32_t upper_limit) { | |
| 3087 upper_limit_ = upper_limit; | |
| 3088 } | |
| 3089 | |
| 3090 bool processed() { return processed_; } | |
| 3091 void set_processed() { processed_ = true; } | |
| 3092 | |
| 3093 InductionVariableCheck(HBoundsCheck* check, | |
| 3094 InductionVariableCheck* next, | |
| 3095 int32_t upper_limit = kNoLimit) | |
| 3096 : check_(check), next_(next), upper_limit_(upper_limit), | |
| 3097 processed_(false) {} | |
| 3098 | |
| 3099 private: | |
| 3100 HBoundsCheck* check_; | |
| 3101 InductionVariableCheck* next_; | |
| 3102 int32_t upper_limit_; | |
| 3103 bool processed_; | |
| 3104 }; | |
| 3105 | |
| 3106 class ChecksRelatedToLength : public ZoneObject { | |
| 3107 public: | |
| 3108 HValue* length() { return length_; } | |
| 3109 ChecksRelatedToLength* next() { return next_; } | |
| 3110 InductionVariableCheck* checks() { return checks_; } | |
| 3111 | |
| 3112 void AddCheck(HBoundsCheck* check, int32_t upper_limit = kNoLimit); | |
| 3113 void CloseCurrentBlock(); | |
| 3114 | |
| 3115 ChecksRelatedToLength(HValue* length, ChecksRelatedToLength* next) | |
| 3116 : length_(length), next_(next), checks_(NULL), | |
| 3117 first_check_in_block_(NULL), | |
| 3118 added_index_(NULL), | |
| 3119 added_constant_(NULL), | |
| 3120 current_and_mask_in_block_(0), | |
| 3121 current_or_mask_in_block_(0) {} | |
| 3122 | |
| 3123 private: | |
| 3124 void UseNewIndexInCurrentBlock(Token::Value token, | |
| 3125 int32_t mask, | |
| 3126 HValue* index_base, | |
| 3127 HValue* context); | |
| 3128 | |
| 3129 HBoundsCheck* first_check_in_block() { return first_check_in_block_; } | |
| 3130 HBitwise* added_index() { return added_index_; } | |
| 3131 void set_added_index(HBitwise* index) { added_index_ = index; } | |
| 3132 HConstant* added_constant() { return added_constant_; } | |
| 3133 void set_added_constant(HConstant* constant) { added_constant_ = constant; } | |
| 3134 int32_t current_and_mask_in_block() { return current_and_mask_in_block_; } | |
| 3135 int32_t current_or_mask_in_block() { return current_or_mask_in_block_; } | |
| 3136 int32_t current_upper_limit() { return current_upper_limit_; } | |
| 3137 | |
| 3138 HValue* length_; | |
| 3139 ChecksRelatedToLength* next_; | |
| 3140 InductionVariableCheck* checks_; | |
| 3141 | |
| 3142 HBoundsCheck* first_check_in_block_; | |
| 3143 HBitwise* added_index_; | |
| 3144 HConstant* added_constant_; | |
| 3145 int32_t current_and_mask_in_block_; | |
| 3146 int32_t current_or_mask_in_block_; | |
| 3147 int32_t current_upper_limit_; | |
| 3148 }; | |
| 3149 | |
| 3150 struct LimitFromPredecessorBlock { | |
| 3151 InductionVariableData* variable; | |
| 3152 Token::Value token; | |
| 3153 HValue* limit; | |
| 3154 HBasicBlock* other_target; | |
| 3155 | |
| 3156 bool LimitIsValid() { return token != Token::ILLEGAL; } | |
| 3157 | |
| 3158 bool LimitIsIncluded() { | |
| 3159 return Token::IsEqualityOp(token) || | |
| 3160 token == Token::GTE || token == Token::LTE; | |
| 3161 } | |
| 3162 bool LimitIsUpper() { | |
| 3163 return token == Token::LTE || token == Token::LT || token == Token::NE; | |
| 3164 } | |
| 3165 | |
| 3166 LimitFromPredecessorBlock() | |
| 3167 : variable(NULL), | |
| 3168 token(Token::ILLEGAL), | |
| 3169 limit(NULL), | |
| 3170 other_target(NULL) {} | |
| 3171 }; | |
| 3172 | |
| 3173 static const int32_t kNoLimit = -1; | |
| 3174 | |
| 3175 static InductionVariableData* ExaminePhi(HPhi* phi); | |
| 3176 static void ComputeLimitFromPredecessorBlock( | |
| 3177 HBasicBlock* block, | |
| 3178 LimitFromPredecessorBlock* result); | |
| 3179 static bool ComputeInductionVariableLimit( | |
| 3180 HBasicBlock* block, | |
| 3181 InductionVariableLimitUpdate* additional_limit); | |
| 3182 | |
| 3183 struct BitwiseDecompositionResult { | |
| 3184 HValue* base; | |
| 3185 int32_t and_mask; | |
| 3186 int32_t or_mask; | |
| 3187 HValue* context; | |
| 3188 | |
| 3189 BitwiseDecompositionResult() | |
| 3190 : base(NULL), and_mask(0), or_mask(0), context(NULL) {} | |
| 3191 }; | |
| 3192 static void DecomposeBitwise(HValue* value, | |
| 3193 BitwiseDecompositionResult* result); | |
| 3194 | |
| 3195 void AddCheck(HBoundsCheck* check, int32_t upper_limit = kNoLimit); | |
| 3196 | |
| 3197 bool CheckIfBranchIsLoopGuard(Token::Value token, | |
| 3198 HBasicBlock* current_branch, | |
| 3199 HBasicBlock* other_branch); | |
| 3200 | |
| 3201 void UpdateAdditionalLimit(InductionVariableLimitUpdate* update) { | |
|
titzer
2013/07/11 16:39:10
Also put this into the .cc file please.
And why a
Massi
2013/07/12 08:20:24
Done.
We are swapping because of the need for back
| |
| 3202 ASSERT(update->updated_variable == this); | |
| 3203 if (update->limit_is_upper) { | |
| 3204 swap(&additional_upper_limit_, &update->limit); | |
| 3205 swap(&additional_upper_limit_is_included_, &update->limit_is_included); | |
| 3206 } else { | |
| 3207 swap(&additional_lower_limit_, &update->limit); | |
| 3208 swap(&additional_lower_limit_is_included_, &update->limit_is_included); | |
| 3209 } | |
| 3210 } | |
| 3211 | |
| 3212 HPhi* phi() { return phi_; } | |
| 3213 HValue* base() { return base_; } | |
| 3214 int32_t increment() { return increment_; } | |
| 3215 HValue* limit() { return limit_; } | |
| 3216 bool limit_included() { return limit_included_; } | |
| 3217 HBasicBlock* limit_validity() { return limit_validity_; } | |
| 3218 HBasicBlock* induction_exit_block() { return induction_exit_block_; } | |
| 3219 HBasicBlock* induction_exit_target() { return induction_exit_target_; } | |
| 3220 ChecksRelatedToLength* checks() { return checks_; } | |
| 3221 HValue* additional_upper_limit() { return additional_upper_limit_; } | |
| 3222 bool additional_upper_limit_is_included() { | |
| 3223 return additional_upper_limit_is_included_; | |
| 3224 } | |
| 3225 HValue* additional_lower_limit() { return additional_lower_limit_; } | |
| 3226 bool additional_lower_limit_is_included() { | |
| 3227 return additional_lower_limit_is_included_; | |
| 3228 } | |
| 3229 | |
| 3230 bool lower_limit_is_non_negative_constant() { | |
|
titzer
2013/07/11 16:39:10
hacker_style is supposedly only for accessors.
Massi
2013/07/12 08:20:24
Done.
| |
| 3231 if (base()->IsInteger32Constant() && base()->GetInteger32Constant() >= 0) { | |
| 3232 return true; | |
| 3233 } | |
| 3234 if (additional_lower_limit() != NULL && | |
| 3235 additional_lower_limit()->IsInteger32Constant() && | |
| 3236 additional_lower_limit()->GetInteger32Constant() >= 0) { | |
| 3237 // Ignoring the corner case of !additional_lower_limit_is_included() | |
| 3238 // is safe, handling it adds unneeded complexity. | |
| 3239 return true; | |
| 3240 } | |
| 3241 return false; | |
| 3242 } | |
| 3243 | |
| 3244 int32_t ComputeUpperLimit(int32_t and_mask, int32_t or_mask) { | |
|
titzer
2013/07/11 16:39:10
Put this one in the .cc file.
Massi
2013/07/12 08:20:24
Done.
| |
| 3245 // Should be Smi::kMaxValue but it must fit 32 bits; lower is safe anyway. | |
| 3246 const int32_t MAX_LIMIT = 1 << 30; | |
| 3247 | |
| 3248 int32_t result = MAX_LIMIT; | |
| 3249 | |
| 3250 if (limit() != NULL && | |
| 3251 limit()->IsInteger32Constant()) { | |
| 3252 int32_t limit_value = limit()->GetInteger32Constant(); | |
| 3253 if (!limit_included()) { | |
| 3254 limit_value--; | |
| 3255 } | |
| 3256 if (limit_value < result) result = limit_value; | |
| 3257 } | |
| 3258 | |
| 3259 if (additional_upper_limit() != NULL && | |
| 3260 additional_upper_limit()->IsInteger32Constant()) { | |
| 3261 int32_t limit_value = additional_upper_limit()->GetInteger32Constant(); | |
| 3262 if (!additional_upper_limit_is_included()) { | |
| 3263 limit_value--; | |
| 3264 } | |
| 3265 if (limit_value < result) result = limit_value; | |
| 3266 } | |
| 3267 | |
| 3268 if (and_mask > 0 && and_mask < MAX_LIMIT) { | |
| 3269 if (and_mask < result) result = and_mask; | |
| 3270 return result; | |
| 3271 } | |
| 3272 | |
| 3273 // Add the effect of the or_mask. | |
| 3274 result |= or_mask; | |
| 3275 | |
| 3276 if (result >= MAX_LIMIT) { | |
| 3277 result = kNoLimit; | |
| 3278 } | |
| 3279 return result; | |
| 3280 } | |
| 3281 | |
| 3282 private: | |
| 3283 template <class T> void swap(T* a, T* b) { | |
| 3284 T c(*a); | |
| 3285 *a = *b; | |
| 3286 *b = c; | |
| 3287 } | |
| 3288 | |
| 3289 InductionVariableData(HPhi* phi, HValue* base, int32_t increment) | |
| 3290 : phi_(phi), base_(IgnoreOsrValue(base)), increment_(increment), | |
| 3291 limit_(NULL), limit_included_(false), limit_validity_(NULL), | |
| 3292 induction_exit_block_(NULL), induction_exit_target_(NULL), | |
| 3293 checks_(NULL), | |
| 3294 additional_upper_limit_(NULL), | |
| 3295 additional_upper_limit_is_included_(false), | |
| 3296 additional_lower_limit_(NULL), | |
| 3297 additional_lower_limit_is_included_(false) {} | |
| 3298 | |
| 3299 static int32_t ComputeIncrement(HPhi* phi, HValue* phi_operand); | |
| 3300 | |
| 3301 static HValue* IgnoreOsrValue(HValue* v); | |
| 3302 static InductionVariableData* GetInductionVariableData(HValue* v); | |
| 3303 | |
| 3304 HPhi* phi_; | |
| 3305 HValue* base_; | |
| 3306 int32_t increment_; | |
| 3307 HValue* limit_; | |
| 3308 bool limit_included_; | |
| 3309 HBasicBlock* limit_validity_; | |
| 3310 HBasicBlock* induction_exit_block_; | |
| 3311 HBasicBlock* induction_exit_target_; | |
| 3312 ChecksRelatedToLength* checks_; | |
| 3313 HValue* additional_upper_limit_; | |
| 3314 bool additional_upper_limit_is_included_; | |
| 3315 HValue* additional_lower_limit_; | |
| 3316 bool additional_lower_limit_is_included_; | |
| 3317 }; | |
| 3318 | |
| 3319 | |
| 3053 class HPhi: public HValue { | 3320 class HPhi: public HValue { |
| 3054 public: | 3321 public: |
| 3055 HPhi(int merged_index, Zone* zone) | 3322 HPhi(int merged_index, Zone* zone) |
| 3056 : inputs_(2, zone), | 3323 : inputs_(2, zone), |
| 3057 merged_index_(merged_index), | 3324 merged_index_(merged_index), |
| 3058 phi_id_(-1) { | 3325 phi_id_(-1), |
| 3326 induction_variable_data_(NULL) { | |
| 3059 for (int i = 0; i < Representation::kNumRepresentations; i++) { | 3327 for (int i = 0; i < Representation::kNumRepresentations; i++) { |
| 3060 non_phi_uses_[i] = 0; | 3328 non_phi_uses_[i] = 0; |
| 3061 indirect_uses_[i] = 0; | 3329 indirect_uses_[i] = 0; |
| 3062 } | 3330 } |
| 3063 ASSERT(merged_index >= 0); | 3331 ASSERT(merged_index >= 0); |
| 3064 SetFlag(kFlexibleRepresentation); | 3332 SetFlag(kFlexibleRepresentation); |
| 3065 SetFlag(kAllowUndefinedAsNaN); | 3333 SetFlag(kAllowUndefinedAsNaN); |
| 3066 } | 3334 } |
| 3067 | 3335 |
| 3068 virtual Representation RepresentationFromInputs(); | 3336 virtual Representation RepresentationFromInputs(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 3079 virtual int OperandCount() { return inputs_.length(); } | 3347 virtual int OperandCount() { return inputs_.length(); } |
| 3080 virtual HValue* OperandAt(int index) const { return inputs_[index]; } | 3348 virtual HValue* OperandAt(int index) const { return inputs_[index]; } |
| 3081 HValue* GetRedundantReplacement(); | 3349 HValue* GetRedundantReplacement(); |
| 3082 void AddInput(HValue* value); | 3350 void AddInput(HValue* value); |
| 3083 bool HasRealUses(); | 3351 bool HasRealUses(); |
| 3084 | 3352 |
| 3085 bool IsReceiver() const { return merged_index_ == 0; } | 3353 bool IsReceiver() const { return merged_index_ == 0; } |
| 3086 | 3354 |
| 3087 int merged_index() const { return merged_index_; } | 3355 int merged_index() const { return merged_index_; } |
| 3088 | 3356 |
| 3357 InductionVariableData* induction_variable_data() { | |
| 3358 return induction_variable_data_; | |
| 3359 } | |
| 3360 bool IsInductionVariable() { | |
| 3361 return induction_variable_data_ != NULL; | |
| 3362 } | |
| 3363 bool IsLimitedInductionVariable() { | |
| 3364 return IsInductionVariable() && | |
| 3365 induction_variable_data_->limit() != NULL; | |
| 3366 } | |
| 3367 void DetectInductionVariable() { | |
| 3368 ASSERT(induction_variable_data_ == NULL); | |
| 3369 induction_variable_data_ = InductionVariableData::ExaminePhi(this); | |
| 3370 } | |
| 3371 | |
| 3089 virtual void AddInformativeDefinitions(); | 3372 virtual void AddInformativeDefinitions(); |
| 3090 | 3373 |
| 3091 virtual void PrintTo(StringStream* stream); | 3374 virtual void PrintTo(StringStream* stream); |
| 3092 | 3375 |
| 3093 #ifdef DEBUG | 3376 #ifdef DEBUG |
| 3094 virtual void Verify(); | 3377 virtual void Verify(); |
| 3095 #endif | 3378 #endif |
| 3096 | 3379 |
| 3097 void InitRealUses(int id); | 3380 void InitRealUses(int id); |
| 3098 void AddNonPhiUsesFrom(HPhi* other); | 3381 void AddNonPhiUsesFrom(HPhi* other); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3146 int offset = 0, | 3429 int offset = 0, |
| 3147 int scale = 0); | 3430 int scale = 0); |
| 3148 | 3431 |
| 3149 private: | 3432 private: |
| 3150 ZoneList<HValue*> inputs_; | 3433 ZoneList<HValue*> inputs_; |
| 3151 int merged_index_; | 3434 int merged_index_; |
| 3152 | 3435 |
| 3153 int non_phi_uses_[Representation::kNumRepresentations]; | 3436 int non_phi_uses_[Representation::kNumRepresentations]; |
| 3154 int indirect_uses_[Representation::kNumRepresentations]; | 3437 int indirect_uses_[Representation::kNumRepresentations]; |
| 3155 int phi_id_; | 3438 int phi_id_; |
| 3439 InductionVariableData* induction_variable_data_; | |
| 3156 }; | 3440 }; |
| 3157 | 3441 |
| 3158 | 3442 |
| 3159 class HInductionVariableAnnotation : public HUnaryOperation { | 3443 class HInductionVariableAnnotation : public HUnaryOperation { |
| 3160 public: | 3444 public: |
| 3161 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, | 3445 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, |
| 3162 NumericRelation relation, | 3446 NumericRelation relation, |
| 3163 int operand_index); | 3447 int operand_index); |
| 3164 | 3448 |
| 3165 NumericRelation relation() { return relation_; } | 3449 NumericRelation relation() { return relation_; } |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3653 | 3937 |
| 3654 class HBoundsCheck: public HTemplateInstruction<2> { | 3938 class HBoundsCheck: public HTemplateInstruction<2> { |
| 3655 public: | 3939 public: |
| 3656 // Normally HBoundsCheck should be created using the | 3940 // Normally HBoundsCheck should be created using the |
| 3657 // HGraphBuilder::AddBoundsCheck() helper. | 3941 // HGraphBuilder::AddBoundsCheck() helper. |
| 3658 // However when building stubs, where we know that the arguments are Int32, | 3942 // However when building stubs, where we know that the arguments are Int32, |
| 3659 // it makes sense to invoke this constructor directly. | 3943 // it makes sense to invoke this constructor directly. |
| 3660 HBoundsCheck(HValue* index, HValue* length) | 3944 HBoundsCheck(HValue* index, HValue* length) |
| 3661 : skip_check_(false), | 3945 : skip_check_(false), |
| 3662 base_(NULL), offset_(0), scale_(0), | 3946 base_(NULL), offset_(0), scale_(0), |
| 3663 responsibility_direction_(DIRECTION_NONE) { | 3947 responsibility_direction_(DIRECTION_NONE), |
| 3948 allow_equality_(false) { | |
| 3664 SetOperandAt(0, index); | 3949 SetOperandAt(0, index); |
| 3665 SetOperandAt(1, length); | 3950 SetOperandAt(1, length); |
| 3666 SetFlag(kFlexibleRepresentation); | 3951 SetFlag(kFlexibleRepresentation); |
| 3667 SetFlag(kUseGVN); | 3952 SetFlag(kUseGVN); |
| 3668 } | 3953 } |
| 3669 | 3954 |
| 3670 bool skip_check() { return skip_check_; } | 3955 bool skip_check() const { return skip_check_; } |
| 3671 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } | 3956 void set_skip_check() { skip_check_ = true; } |
| 3672 HValue* base() { return base_; } | 3957 HValue* base() { return base_; } |
| 3673 int offset() { return offset_; } | 3958 int offset() { return offset_; } |
| 3674 int scale() { return scale_; } | 3959 int scale() { return scale_; } |
| 3675 bool index_can_increase() { | 3960 bool index_can_increase() { |
| 3676 return (responsibility_direction_ & DIRECTION_LOWER) == 0; | 3961 return (responsibility_direction_ & DIRECTION_LOWER) == 0; |
| 3677 } | 3962 } |
| 3678 bool index_can_decrease() { | 3963 bool index_can_decrease() { |
| 3679 return (responsibility_direction_ & DIRECTION_UPPER) == 0; | 3964 return (responsibility_direction_ & DIRECTION_UPPER) == 0; |
| 3680 } | 3965 } |
| 3681 | 3966 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3693 base_ = index(); | 3978 base_ = index(); |
| 3694 offset_ = 0; | 3979 offset_ = 0; |
| 3695 scale_ = 0; | 3980 scale_ = 0; |
| 3696 return false; | 3981 return false; |
| 3697 } | 3982 } |
| 3698 } | 3983 } |
| 3699 | 3984 |
| 3700 virtual Representation RequiredInputRepresentation(int arg_index) { | 3985 virtual Representation RequiredInputRepresentation(int arg_index) { |
| 3701 return representation(); | 3986 return representation(); |
| 3702 } | 3987 } |
| 3988 virtual bool IsDeletable() const { | |
| 3989 return skip_check() && !FLAG_debug_code; | |
| 3990 } | |
| 3703 | 3991 |
| 3704 virtual bool IsRelationTrueInternal(NumericRelation relation, | 3992 virtual bool IsRelationTrueInternal(NumericRelation relation, |
| 3705 HValue* related_value, | 3993 HValue* related_value, |
| 3706 int offset = 0, | 3994 int offset = 0, |
| 3707 int scale = 0); | 3995 int scale = 0); |
| 3708 | 3996 |
| 3709 virtual void PrintDataTo(StringStream* stream); | 3997 virtual void PrintDataTo(StringStream* stream); |
| 3710 virtual void InferRepresentation(HInferRepresentation* h_infer); | 3998 virtual void InferRepresentation(HInferRepresentation* h_infer); |
| 3711 | 3999 |
| 3712 HValue* index() { return OperandAt(0); } | 4000 HValue* index() { return OperandAt(0); } |
| 3713 HValue* length() { return OperandAt(1); } | 4001 HValue* length() { return OperandAt(1); } |
| 4002 bool allow_equality() { return allow_equality_; } | |
| 4003 void set_allow_equality(bool v) { allow_equality_ = v; } | |
| 3714 | 4004 |
| 3715 virtual int RedefinedOperandIndex() { return 0; } | 4005 virtual int RedefinedOperandIndex() { return 0; } |
| 3716 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } | 4006 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } |
| 3717 virtual void AddInformativeDefinitions(); | 4007 virtual void AddInformativeDefinitions(); |
| 3718 | 4008 |
| 3719 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 4009 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |
| 3720 | 4010 |
| 3721 protected: | 4011 protected: |
| 3722 friend class HBoundsCheckBaseIndexInformation; | 4012 friend class HBoundsCheckBaseIndexInformation; |
| 3723 | 4013 |
| 3724 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { | 4014 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { |
| 3725 responsibility_direction_ = static_cast<RangeGuaranteeDirection>( | 4015 responsibility_direction_ = static_cast<RangeGuaranteeDirection>( |
| 3726 responsibility_direction_ | direction); | 4016 responsibility_direction_ | direction); |
| 3727 } | 4017 } |
| 3728 | 4018 |
| 3729 virtual bool DataEquals(HValue* other) { return true; } | 4019 virtual bool DataEquals(HValue* other) { return true; } |
| 3730 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); | 4020 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); |
| 3731 bool skip_check_; | 4021 bool skip_check_; |
| 3732 HValue* base_; | 4022 HValue* base_; |
| 3733 int offset_; | 4023 int offset_; |
| 3734 int scale_; | 4024 int scale_; |
| 3735 RangeGuaranteeDirection responsibility_direction_; | 4025 RangeGuaranteeDirection responsibility_direction_; |
| 4026 bool allow_equality_; | |
| 3736 }; | 4027 }; |
| 3737 | 4028 |
| 3738 | 4029 |
| 3739 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { | 4030 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { |
| 3740 public: | 4031 public: |
| 3741 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { | 4032 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { |
| 3742 DecompositionResult decomposition; | 4033 DecompositionResult decomposition; |
| 3743 if (check->index()->TryDecompose(&decomposition)) { | 4034 if (check->index()->TryDecompose(&decomposition)) { |
| 3744 SetOperandAt(0, decomposition.base()); | 4035 SetOperandAt(0, decomposition.base()); |
| 3745 SetOperandAt(1, check); | 4036 SetOperandAt(1, check); |
| (...skipping 2855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6601 virtual HType CalculateInferredType() { | 6892 virtual HType CalculateInferredType() { |
| 6602 return HType::Tagged(); | 6893 return HType::Tagged(); |
| 6603 } | 6894 } |
| 6604 | 6895 |
| 6605 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); | 6896 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); |
| 6606 | 6897 |
| 6607 private: | 6898 private: |
| 6608 virtual bool IsDeletable() const { return true; } | 6899 virtual bool IsDeletable() const { return true; } |
| 6609 }; | 6900 }; |
| 6610 | 6901 |
| 6611 | |
| 6612 #undef DECLARE_INSTRUCTION | 6902 #undef DECLARE_INSTRUCTION |
| 6613 #undef DECLARE_CONCRETE_INSTRUCTION | 6903 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6614 | 6904 |
| 6615 } } // namespace v8::internal | 6905 } } // namespace v8::internal |
| 6616 | 6906 |
| 6617 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6907 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |