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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 | 227 |
228 #define DECLARE_CONCRETE_INSTRUCTION(type) \ | 228 #define DECLARE_CONCRETE_INSTRUCTION(type) \ |
229 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \ | 229 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \ |
230 static H##type* cast(HValue* value) { \ | 230 static H##type* cast(HValue* value) { \ |
231 ASSERT(value->Is##type()); \ | 231 ASSERT(value->Is##type()); \ |
232 return reinterpret_cast<H##type*>(value); \ | 232 return reinterpret_cast<H##type*>(value); \ |
233 } \ | 233 } \ |
234 virtual Opcode opcode() const { return HValue::k##type; } | 234 virtual Opcode opcode() const { return HValue::k##type; } |
235 | 235 |
236 | 236 |
237 #ifdef DEBUG | |
238 #define ASSERT_ALLOCATION_DISABLED \ | |
239 ASSERT(isolate()->optimizing_compiler_thread()->IsOptimizerThread() || \ | |
240 !isolate()->heap()->IsAllocationAllowed()) | |
241 #else | |
242 #define ASSERT_ALLOCATION_DISABLED do {} while (0) | |
243 #endif | |
244 | |
245 class Range: public ZoneObject { | 237 class Range: public ZoneObject { |
246 public: | 238 public: |
247 Range() | 239 Range() |
248 : lower_(kMinInt), | 240 : lower_(kMinInt), |
249 upper_(kMaxInt), | 241 upper_(kMaxInt), |
250 next_(NULL), | 242 next_(NULL), |
251 can_be_minus_zero_(false) { } | 243 can_be_minus_zero_(false) { } |
252 | 244 |
253 Range(int32_t lower, int32_t upper) | 245 Range(int32_t lower, int32_t upper) |
254 : lower_(lower), | 246 : lower_(lower), |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1050 | 1042 |
1051 // This gives the instruction an opportunity to replace itself with an | 1043 // This gives the instruction an opportunity to replace itself with an |
1052 // instruction that does the same in some better way. To replace an | 1044 // instruction that does the same in some better way. To replace an |
1053 // instruction with a new one, first add the new instruction to the graph, | 1045 // instruction with a new one, first add the new instruction to the graph, |
1054 // then return it. Return NULL to have the instruction deleted. | 1046 // then return it. Return NULL to have the instruction deleted. |
1055 virtual HValue* Canonicalize() { return this; } | 1047 virtual HValue* Canonicalize() { return this; } |
1056 | 1048 |
1057 bool Equals(HValue* other); | 1049 bool Equals(HValue* other); |
1058 virtual intptr_t Hashcode(); | 1050 virtual intptr_t Hashcode(); |
1059 | 1051 |
1052 // Some instructions' hash code is dependent on object addresses and are not | |
1053 // safe regarding GC and parallel recompilation. Compute the hash upfront. | |
1054 virtual void FinalizeHashcode() { } | |
1055 | |
1060 // Printing support. | 1056 // Printing support. |
1061 virtual void PrintTo(StringStream* stream) = 0; | 1057 virtual void PrintTo(StringStream* stream) = 0; |
1062 void PrintNameTo(StringStream* stream); | 1058 void PrintNameTo(StringStream* stream); |
1063 void PrintTypeTo(StringStream* stream); | 1059 void PrintTypeTo(StringStream* stream); |
1064 void PrintRangeTo(StringStream* stream); | 1060 void PrintRangeTo(StringStream* stream); |
1065 void PrintChangesTo(StringStream* stream); | 1061 void PrintChangesTo(StringStream* stream); |
1066 | 1062 |
1067 const char* Mnemonic() const; | 1063 const char* Mnemonic() const; |
1068 | 1064 |
1069 // Type information helpers. | 1065 // Type information helpers. |
(...skipping 1779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2849 | 2845 |
2850 protected: | 2846 protected: |
2851 virtual bool DataEquals(HValue* other) { return true; } | 2847 virtual bool DataEquals(HValue* other) { return true; } |
2852 }; | 2848 }; |
2853 | 2849 |
2854 | 2850 |
2855 class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 2851 class HCheckPrototypeMaps: public HTemplateInstruction<0> { |
2856 public: | 2852 public: |
2857 HCheckPrototypeMaps(Handle<JSObject> prototype, | 2853 HCheckPrototypeMaps(Handle<JSObject> prototype, |
2858 Handle<JSObject> holder, | 2854 Handle<JSObject> holder, |
2859 Zone* zone) : prototypes_(2, zone), maps_(2, zone) { | 2855 Zone* zone) |
2856 : prototypes_(2, zone), | |
2857 maps_(2, zone), | |
2858 first_prototype_(NULL), | |
2859 last_prototype_(NULL) { | |
2860 SetFlag(kUseGVN); | 2860 SetFlag(kUseGVN); |
2861 SetGVNFlag(kDependsOnMaps); | 2861 SetGVNFlag(kDependsOnMaps); |
2862 // Keep a list of all objects on the prototype chain up to the holder | 2862 // Keep a list of all objects on the prototype chain up to the holder |
2863 // and the expected maps. | 2863 // and the expected maps. |
2864 while (true) { | 2864 while (true) { |
2865 prototypes_.Add(prototype, zone); | 2865 prototypes_.Add(prototype, zone); |
2866 maps_.Add(Handle<Map>(prototype->map()), zone); | 2866 maps_.Add(Handle<Map>(prototype->map()), zone); |
2867 if (prototype.is_identical_to(holder)) break; | 2867 if (prototype.is_identical_to(holder)) break; |
2868 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype())); | 2868 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype())); |
2869 } | 2869 } |
2870 } | 2870 } |
2871 | 2871 |
2872 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; } | 2872 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; } |
2873 | 2873 |
2874 ZoneList<Handle<Map> >* maps() { return &maps_; } | 2874 ZoneList<Handle<Map> >* maps() { return &maps_; } |
2875 | 2875 |
2876 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) | 2876 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) |
2877 | 2877 |
2878 virtual Representation RequiredInputRepresentation(int index) { | 2878 virtual Representation RequiredInputRepresentation(int index) { |
2879 return Representation::None(); | 2879 return Representation::None(); |
2880 } | 2880 } |
2881 | 2881 |
2882 virtual void PrintDataTo(StringStream* stream); | 2882 virtual void PrintDataTo(StringStream* stream); |
2883 | 2883 |
2884 virtual intptr_t Hashcode() { | 2884 virtual intptr_t Hashcode() { |
2885 ASSERT_ALLOCATION_DISABLED; | 2885 ASSERT_NE(NULL, first_prototype_); |
2886 // Dereferencing to use the object's raw address for hashing is safe. | 2886 return reinterpret_cast<intptr_t>(first_prototype_) * 17 + |
2887 HandleDereferenceGuard allow_handle_deref(isolate(), | 2887 reinterpret_cast<intptr_t>(last_prototype_); |
2888 HandleDereferenceGuard::ALLOW); | 2888 } |
2889 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || | 2889 |
2890 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); | 2890 virtual void FinalizeHashcode() { |
2891 intptr_t hash = 0; | 2891 ASSERT(first_prototype_ == 0 || |
2892 for (int i = 0; i < prototypes_.length(); i++) { | 2892 first_prototype_ == reinterpret_cast<Address>(*prototypes_.first())); |
2893 hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]); | 2893 first_prototype_ = reinterpret_cast<Address>(*prototypes_.first()); |
2894 hash = 17 * hash + reinterpret_cast<intptr_t>(*maps_[i]); | 2894 ASSERT(last_prototype_ == 0 || |
2895 } | 2895 last_prototype_ == reinterpret_cast<Address>(*prototypes_.last())); |
2896 return hash; | 2896 last_prototype_ = reinterpret_cast<Address>(*prototypes_.last()); |
2897 } | 2897 } |
2898 | 2898 |
2899 bool CanOmitPrototypeChecks() { | 2899 bool CanOmitPrototypeChecks() { |
2900 for (int i = 0; i < maps()->length(); i++) { | 2900 for (int i = 0; i < maps()->length(); i++) { |
2901 if (!maps()->at(i)->CanOmitPrototypeChecks()) return false; | 2901 if (!maps()->at(i)->CanOmitPrototypeChecks()) return false; |
2902 } | 2902 } |
2903 return true; | 2903 return true; |
2904 } | 2904 } |
2905 | 2905 |
2906 protected: | 2906 protected: |
2907 virtual bool DataEquals(HValue* other) { | 2907 virtual bool DataEquals(HValue* other) { |
2908 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); | 2908 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); |
2909 #ifdef DEBUG | 2909 ASSERT_NE(0, first_prototype_); |
2910 if (prototypes_.length() != b->prototypes()->length()) return false; | 2910 return first_prototype_ == b->first_prototype_ && |
2911 for (int i = 0; i < prototypes_.length(); i++) { | 2911 last_prototype_ == b->last_prototype_; |
2912 if (!prototypes_[i].is_identical_to(b->prototypes()->at(i))) return false; | |
2913 if (!maps_[i].is_identical_to(b->maps()->at(i))) return false; | |
2914 } | |
2915 return true; | |
2916 #else | |
2917 return prototypes_.first().is_identical_to(b->prototypes()->first()) && | |
2918 prototypes_.last().is_identical_to(b->prototypes()->last()); | |
2919 #endif // DEBUG | |
2920 } | 2912 } |
2921 | 2913 |
2922 private: | 2914 private: |
2923 ZoneList<Handle<JSObject> > prototypes_; | 2915 ZoneList<Handle<JSObject> > prototypes_; |
2924 ZoneList<Handle<Map> > maps_; | 2916 ZoneList<Handle<Map> > maps_; |
2917 Address first_prototype_; | |
2918 Address last_prototype_; | |
2925 }; | 2919 }; |
2926 | 2920 |
2927 | 2921 |
2928 class HCheckSmi: public HUnaryOperation { | 2922 class HCheckSmi: public HUnaryOperation { |
2929 public: | 2923 public: |
2930 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { | 2924 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { |
2931 set_representation(Representation::Tagged()); | 2925 set_representation(Representation::Tagged()); |
2932 SetFlag(kUseGVN); | 2926 SetFlag(kUseGVN); |
2933 } | 2927 } |
2934 | 2928 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3169 class HConstant: public HTemplateInstruction<0> { | 3163 class HConstant: public HTemplateInstruction<0> { |
3170 public: | 3164 public: |
3171 HConstant(Handle<Object> handle, Representation r); | 3165 HConstant(Handle<Object> handle, Representation r); |
3172 HConstant(int32_t value, | 3166 HConstant(int32_t value, |
3173 Representation r, | 3167 Representation r, |
3174 Handle<Object> optional_handle = Handle<Object>::null()); | 3168 Handle<Object> optional_handle = Handle<Object>::null()); |
3175 HConstant(double value, | 3169 HConstant(double value, |
3176 Representation r, | 3170 Representation r, |
3177 Handle<Object> optional_handle = Handle<Object>::null()); | 3171 Handle<Object> optional_handle = Handle<Object>::null()); |
3178 HConstant(Handle<Object> handle, | 3172 HConstant(Handle<Object> handle, |
3173 Address raw_address, | |
3179 Representation r, | 3174 Representation r, |
3180 HType type, | 3175 HType type, |
3181 bool is_internalized_string, | 3176 bool is_internalized_string, |
3182 bool boolean_value); | 3177 bool boolean_value); |
3183 | 3178 |
3184 Handle<Object> handle() { | 3179 Handle<Object> handle() { |
3185 if (handle_.is_null()) { | 3180 if (handle_.is_null()) { |
3186 handle_ = FACTORY->NewNumber(double_value_, TENURED); | 3181 handle_ = FACTORY->NewNumber(double_value_, TENURED); |
3187 } | 3182 } |
3188 ASSERT(has_int32_value_ || !handle_->IsSmi()); | 3183 ASSERT(has_int32_value_ || !handle_->IsSmi()); |
3189 return handle_; | 3184 return handle_; |
3190 } | 3185 } |
3191 | 3186 |
3192 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } | |
3193 | |
3194 bool IsSpecialDouble() const { | 3187 bool IsSpecialDouble() const { |
3195 return has_double_value_ && | 3188 return has_double_value_ && |
3196 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || | 3189 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || |
3197 FixedDoubleArray::is_the_hole_nan(double_value_) || | 3190 FixedDoubleArray::is_the_hole_nan(double_value_) || |
3198 isnan(double_value_)); | 3191 isnan(double_value_)); |
3199 } | 3192 } |
3200 | 3193 |
3201 bool ImmortalImmovable() const { | 3194 bool ImmortalImmovable() const { |
3202 if (has_int32_value_) { | 3195 if (has_int32_value_) { |
3203 return false; | 3196 return false; |
3204 } | 3197 } |
3205 if (has_double_value_) { | 3198 if (has_double_value_) { |
3206 if (IsSpecialDouble()) { | 3199 if (IsSpecialDouble()) { |
3207 return true; | 3200 return true; |
3208 } | 3201 } |
3209 return false; | 3202 return false; |
3210 } | 3203 } |
3211 | 3204 |
3212 ASSERT(!handle_.is_null()); | 3205 ASSERT(!handle_.is_null()); |
3213 Heap* heap = isolate()->heap(); | 3206 Heap* heap = isolate()->heap(); |
3214 // We should have handled minus_zero_value and nan_value in the | 3207 // The raw address is sufficient to compare against root list entries. |
3215 // has_double_value_ clause above. | 3208 Object* obj = reinterpret_cast<Object*>(raw_address_); |
3216 // Dereferencing is safe to compare against immovable singletons. | 3209 ASSERT(obj != heap->minus_zero_value()); |
3217 HandleDereferenceGuard allow_handle_deref(isolate(), | 3210 ASSERT(obj != heap->nan_value()); |
3218 HandleDereferenceGuard::ALLOW); | 3211 return obj == heap->undefined_value() || |
3219 ASSERT(*handle_ != heap->minus_zero_value()); | 3212 obj == heap->null_value() || |
3220 ASSERT(*handle_ != heap->nan_value()); | 3213 obj == heap->true_value() || |
3221 return *handle_ == heap->undefined_value() || | 3214 obj == heap->false_value() || |
3222 *handle_ == heap->null_value() || | 3215 obj == heap->the_hole_value() || |
3223 *handle_ == heap->true_value() || | 3216 obj == heap->empty_string(); |
3224 *handle_ == heap->false_value() || | |
3225 *handle_ == heap->the_hole_value() || | |
3226 *handle_ == heap->empty_string(); | |
3227 } | 3217 } |
3228 | 3218 |
3229 virtual Representation RequiredInputRepresentation(int index) { | 3219 virtual Representation RequiredInputRepresentation(int index) { |
3230 return Representation::None(); | 3220 return Representation::None(); |
3231 } | 3221 } |
3232 | 3222 |
3233 virtual bool IsConvertibleToInteger() const { | 3223 virtual bool IsConvertibleToInteger() const { |
3234 return has_int32_value_; | 3224 return has_int32_value_; |
3235 } | 3225 } |
3236 | 3226 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3286 return HasStringValue() && is_internalized_string_; | 3276 return HasStringValue() && is_internalized_string_; |
3287 } | 3277 } |
3288 | 3278 |
3289 bool BooleanValue() const { return boolean_value_; } | 3279 bool BooleanValue() const { return boolean_value_; } |
3290 | 3280 |
3291 bool IsUint32() { | 3281 bool IsUint32() { |
3292 return HasInteger32Value() && (Integer32Value() >= 0); | 3282 return HasInteger32Value() && (Integer32Value() >= 0); |
3293 } | 3283 } |
3294 | 3284 |
3295 virtual intptr_t Hashcode() { | 3285 virtual intptr_t Hashcode() { |
3296 ASSERT_ALLOCATION_DISABLED; | |
3297 intptr_t hash; | |
3298 | |
3299 if (has_int32_value_) { | 3286 if (has_int32_value_) { |
3300 hash = static_cast<intptr_t>(int32_value_); | 3287 return static_cast<intptr_t>(int32_value_); |
3301 } else if (has_double_value_) { | 3288 } else if (has_double_value_) { |
3302 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3289 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
3303 } else { | 3290 } else { |
3304 ASSERT(!handle_.is_null()); | 3291 ASSERT(!handle_.is_null()); |
3305 // Dereferencing to use the object's raw address for hashing is safe. | 3292 ASSERT_NE(NULL, raw_address_); |
3306 HandleDereferenceGuard allow_handle_deref(isolate(), | 3293 return reinterpret_cast<intptr_t>(raw_address_); |
3307 HandleDereferenceGuard::ALLOW); | |
3308 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || | |
3309 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); | |
3310 hash = reinterpret_cast<intptr_t>(*handle_); | |
3311 } | 3294 } |
3295 } | |
3312 | 3296 |
3313 return hash; | 3297 virtual void FinalizeHashcode() { |
3298 if (!has_double_value_) { | |
Sven Panne
2013/04/12 11:30:53
What about has_int32_value_?
Yang
2013/04/15 13:55:31
Done.
| |
3299 ASSERT(!handle_.is_null()); | |
3300 // Hash code has not been set, or already set to the same value. | |
3301 ASSERT(raw_address_ == NULL || | |
3302 raw_address_ == reinterpret_cast<Address>(*handle_)); | |
3303 raw_address_ = reinterpret_cast<Address>(*handle_); | |
3304 } | |
3314 } | 3305 } |
3315 | 3306 |
3316 #ifdef DEBUG | 3307 #ifdef DEBUG |
3317 virtual void Verify() { } | 3308 virtual void Verify() { } |
3318 #endif | 3309 #endif |
3319 | 3310 |
3320 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3311 DECLARE_CONCRETE_INSTRUCTION(Constant) |
3321 | 3312 |
3322 protected: | 3313 protected: |
3323 virtual Range* InferRange(Zone* zone); | 3314 virtual Range* InferRange(Zone* zone); |
3324 | 3315 |
3325 virtual bool DataEquals(HValue* other) { | 3316 virtual bool DataEquals(HValue* other) { |
3326 HConstant* other_constant = HConstant::cast(other); | 3317 HConstant* other_constant = HConstant::cast(other); |
3327 if (has_int32_value_) { | 3318 if (has_int32_value_) { |
3328 return other_constant->has_int32_value_ && | 3319 return other_constant->has_int32_value_ && |
3329 int32_value_ == other_constant->int32_value_; | 3320 int32_value_ == other_constant->int32_value_; |
3330 } else if (has_double_value_) { | 3321 } else if (has_double_value_) { |
3331 return other_constant->has_double_value_ && | 3322 return other_constant->has_double_value_ && |
3332 BitCast<int64_t>(double_value_) == | 3323 BitCast<int64_t>(double_value_) == |
3333 BitCast<int64_t>(other_constant->double_value_); | 3324 BitCast<int64_t>(other_constant->double_value_); |
3334 } else { | 3325 } else { |
3335 ASSERT(!handle_.is_null()); | 3326 ASSERT(!handle_.is_null()); |
3327 ASSERT_NE(NULL, raw_address_); | |
3336 return !other_constant->handle_.is_null() && | 3328 return !other_constant->handle_.is_null() && |
3337 handle_.is_identical_to(other_constant->handle_); | 3329 raw_address_ == other_constant->raw_address_; |
3338 } | 3330 } |
3339 } | 3331 } |
3340 | 3332 |
3341 private: | 3333 private: |
3342 void Initialize(Representation r); | 3334 void Initialize(Representation r); |
3343 | 3335 |
3344 virtual bool IsDeletable() const { return true; } | 3336 virtual bool IsDeletable() const { return true; } |
3345 | 3337 |
3346 // If this is a numerical constant, handle_ either points to to the | 3338 // If this is a numerical constant, handle_ either points to to the |
3347 // HeapObject the constant originated from or is null. If the | 3339 // HeapObject the constant originated from or is null. If the |
3348 // constant is non-numeric, handle_ always points to a valid | 3340 // constant is non-numeric, handle_ always points to a valid |
3349 // constant HeapObject. | 3341 // constant HeapObject. |
3350 Handle<Object> handle_; | 3342 Handle<Object> handle_; |
3351 | 3343 |
3352 // We store the HConstant in the most specific form safely possible. | 3344 // We store the HConstant in the most specific form safely possible. |
3353 // The two flags, has_int32_value_ and has_double_value_ tell us if | 3345 // The two flags, has_int32_value_ and has_double_value_ tell us if |
3354 // int32_value_ and double_value_ hold valid, safe representations | 3346 // int32_value_ and double_value_ hold valid, safe representations |
3355 // of the constant. has_int32_value_ implies has_double_value_ but | 3347 // of the constant. has_int32_value_ implies has_double_value_ but |
3356 // not the converse. | 3348 // not the converse. |
3357 bool has_int32_value_ : 1; | 3349 bool has_int32_value_ : 1; |
3358 bool has_double_value_ : 1; | 3350 bool has_double_value_ : 1; |
3359 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. | 3351 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
3360 bool boolean_value_ : 1; | 3352 bool boolean_value_ : 1; |
3361 int32_t int32_value_; | 3353 // An extra hash code is only necessary if the value is not a number. |
3354 // So has_double_value_ governs how to interpret the union. | |
Sven Panne
2013/04/12 11:30:53
This is a bit obscure. Wouldn't it be better if we
Yang
2013/04/15 13:55:31
Skipping this comment as discussed offline.
| |
3355 union { | |
3356 int32_t int32_value_; | |
3357 Address raw_address_; | |
3358 }; | |
3362 double double_value_; | 3359 double double_value_; |
3363 HType type_from_value_; | 3360 HType type_from_value_; |
3364 }; | 3361 }; |
3365 | 3362 |
3366 | 3363 |
3367 class HBinaryOperation: public HTemplateInstruction<3> { | 3364 class HBinaryOperation: public HTemplateInstruction<3> { |
3368 public: | 3365 public: |
3369 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3366 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
3370 : observed_output_representation_(Representation::None()) { | 3367 : observed_output_representation_(Representation::None()) { |
3371 ASSERT(left != NULL && right != NULL); | 3368 ASSERT(left != NULL && right != NULL); |
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4752 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) | 4749 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) |
4753 | 4750 |
4754 private: | 4751 private: |
4755 HPhi* incoming_value_; | 4752 HPhi* incoming_value_; |
4756 }; | 4753 }; |
4757 | 4754 |
4758 | 4755 |
4759 class HLoadGlobalCell: public HTemplateInstruction<0> { | 4756 class HLoadGlobalCell: public HTemplateInstruction<0> { |
4760 public: | 4757 public: |
4761 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details) | 4758 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details) |
4762 : cell_(cell), details_(details) { | 4759 : cell_(cell), details_(details), hash_code_(0) { |
4763 set_representation(Representation::Tagged()); | 4760 set_representation(Representation::Tagged()); |
4764 SetFlag(kUseGVN); | 4761 SetFlag(kUseGVN); |
4765 SetGVNFlag(kDependsOnGlobalVars); | 4762 SetGVNFlag(kDependsOnGlobalVars); |
4766 } | 4763 } |
4767 | 4764 |
4768 Handle<JSGlobalPropertyCell> cell() const { return cell_; } | 4765 Handle<JSGlobalPropertyCell> cell() const { return cell_; } |
4769 bool RequiresHoleCheck() const; | 4766 bool RequiresHoleCheck() const; |
4770 | 4767 |
4771 virtual void PrintDataTo(StringStream* stream); | 4768 virtual void PrintDataTo(StringStream* stream); |
4772 | 4769 |
4773 virtual intptr_t Hashcode() { | 4770 virtual intptr_t Hashcode() { |
4774 ASSERT_ALLOCATION_DISABLED; | 4771 ASSERT_NE(0, hash_code_); |
4775 // Dereferencing to use the object's raw address for hashing is safe. | 4772 return hash_code_; |
4776 HandleDereferenceGuard allow_handle_deref(isolate(), | 4773 } |
4777 HandleDereferenceGuard::ALLOW); | 4774 |
4778 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || | 4775 virtual void FinalizeHashcode() { |
4779 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); | 4776 // Hash code has not been set, or already set to the same value. |
4780 return reinterpret_cast<intptr_t>(*cell_); | 4777 ASSERT(hash_code_ == 0 || |
4778 hash_code_ == reinterpret_cast<intptr_t>(*cell_)); | |
4779 hash_code_ = reinterpret_cast<intptr_t>(*cell_); | |
4781 } | 4780 } |
4782 | 4781 |
4783 virtual Representation RequiredInputRepresentation(int index) { | 4782 virtual Representation RequiredInputRepresentation(int index) { |
4784 return Representation::None(); | 4783 return Representation::None(); |
4785 } | 4784 } |
4786 | 4785 |
4787 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) | 4786 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) |
4788 | 4787 |
4789 protected: | 4788 protected: |
4790 virtual bool DataEquals(HValue* other) { | 4789 virtual bool DataEquals(HValue* other) { |
4791 HLoadGlobalCell* b = HLoadGlobalCell::cast(other); | 4790 HLoadGlobalCell* b = HLoadGlobalCell::cast(other); |
4792 return cell_.is_identical_to(b->cell()); | 4791 ASSERT_NE(0, hash_code_); |
4792 return hash_code_ == b->hash_code_; | |
4793 } | 4793 } |
4794 | 4794 |
4795 private: | 4795 private: |
4796 virtual bool IsDeletable() const { return !RequiresHoleCheck(); } | 4796 virtual bool IsDeletable() const { return !RequiresHoleCheck(); } |
4797 | 4797 |
4798 Handle<JSGlobalPropertyCell> cell_; | 4798 Handle<JSGlobalPropertyCell> cell_; |
4799 PropertyDetails details_; | 4799 PropertyDetails details_; |
4800 intptr_t hash_code_; | |
Sven Panne
2013/04/12 11:30:53
Renaming this to something like 'unique_id_' makes
Yang
2013/04/15 13:55:31
Done.
| |
4800 }; | 4801 }; |
4801 | 4802 |
4802 | 4803 |
4803 class HLoadGlobalGeneric: public HTemplateInstruction<2> { | 4804 class HLoadGlobalGeneric: public HTemplateInstruction<2> { |
4804 public: | 4805 public: |
4805 HLoadGlobalGeneric(HValue* context, | 4806 HLoadGlobalGeneric(HValue* context, |
4806 HValue* global_object, | 4807 HValue* global_object, |
4807 Handle<Object> name, | 4808 Handle<Object> name, |
4808 bool for_typeof) | 4809 bool for_typeof) |
4809 : name_(name), | 4810 : name_(name), |
(...skipping 1622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6432 virtual bool IsDeletable() const { return true; } | 6433 virtual bool IsDeletable() const { return true; } |
6433 }; | 6434 }; |
6434 | 6435 |
6435 | 6436 |
6436 #undef DECLARE_INSTRUCTION | 6437 #undef DECLARE_INSTRUCTION |
6437 #undef DECLARE_CONCRETE_INSTRUCTION | 6438 #undef DECLARE_CONCRETE_INSTRUCTION |
6438 | 6439 |
6439 } } // namespace v8::internal | 6440 } } // namespace v8::internal |
6440 | 6441 |
6441 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6442 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |