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

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

Issue 14040006: Remove relocation lock. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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());
3206 HandleDereferenceGuard allow_dereference_for_immovable_check(
3207 isolate(), HandleDereferenceGuard::ALLOW);
3208 CHECK_NE(NULL, raw_address_);
Sven Panne 2013/04/12 13:47:02 ASSERT_NE
3209 Object* obj = reinterpret_cast<Object*>(raw_address_);
3213 Heap* heap = isolate()->heap(); 3210 Heap* heap = isolate()->heap();
3214 // We should have handled minus_zero_value and nan_value in the 3211 ASSERT(obj != heap->minus_zero_value());
3215 // has_double_value_ clause above. 3212 ASSERT(obj != heap->nan_value());
3216 // Dereferencing is safe to compare against immovable singletons. 3213 return obj == heap->undefined_value() ||
3217 HandleDereferenceGuard allow_handle_deref(isolate(), 3214 obj == heap->null_value() ||
3218 HandleDereferenceGuard::ALLOW); 3215 obj == heap->true_value() ||
3219 ASSERT(*handle_ != heap->minus_zero_value()); 3216 obj == heap->false_value() ||
3220 ASSERT(*handle_ != heap->nan_value()); 3217 obj == heap->the_hole_value() ||
3221 return *handle_ == heap->undefined_value() || 3218 obj == heap->empty_string();
3222 *handle_ == heap->null_value() ||
3223 *handle_ == heap->true_value() ||
3224 *handle_ == heap->false_value() ||
3225 *handle_ == heap->the_hole_value() ||
3226 *handle_ == heap->empty_string();
3227 } 3219 }
3228 3220
3229 virtual Representation RequiredInputRepresentation(int index) { 3221 virtual Representation RequiredInputRepresentation(int index) {
3230 return Representation::None(); 3222 return Representation::None();
3231 } 3223 }
3232 3224
3233 virtual bool IsConvertibleToInteger() const { 3225 virtual bool IsConvertibleToInteger() const {
3234 return has_int32_value_; 3226 return has_int32_value_;
3235 } 3227 }
3236 3228
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3286 return HasStringValue() && is_internalized_string_; 3278 return HasStringValue() && is_internalized_string_;
3287 } 3279 }
3288 3280
3289 bool BooleanValue() const { return boolean_value_; } 3281 bool BooleanValue() const { return boolean_value_; }
3290 3282
3291 bool IsUint32() { 3283 bool IsUint32() {
3292 return HasInteger32Value() && (Integer32Value() >= 0); 3284 return HasInteger32Value() && (Integer32Value() >= 0);
3293 } 3285 }
3294 3286
3295 virtual intptr_t Hashcode() { 3287 virtual intptr_t Hashcode() {
3296 ASSERT_ALLOCATION_DISABLED;
3297 intptr_t hash;
3298
3299 if (has_int32_value_) { 3288 if (has_int32_value_) {
3300 hash = static_cast<intptr_t>(int32_value_); 3289 return static_cast<intptr_t>(int32_value_);
3301 } else if (has_double_value_) { 3290 } else if (has_double_value_) {
3302 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); 3291 return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3303 } else { 3292 } else {
3304 ASSERT(!handle_.is_null()); 3293 ASSERT(!handle_.is_null());
3305 // Dereferencing to use the object's raw address for hashing is safe. 3294 ASSERT_NE(NULL, raw_address_);
3306 HandleDereferenceGuard allow_handle_deref(isolate(), 3295 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 } 3296 }
3297 }
3312 3298
3313 return hash; 3299 virtual void FinalizeHashcode() {
3300 if (!has_double_value_) {
3301 ASSERT(!handle_.is_null());
3302 // Hash code has not been set, or already set to the same value.
3303 ASSERT(raw_address_ == NULL ||
3304 raw_address_ == reinterpret_cast<Address>(*handle_));
3305 raw_address_ = reinterpret_cast<Address>(*handle_);
3306 }
3314 } 3307 }
3315 3308
3316 #ifdef DEBUG 3309 #ifdef DEBUG
3317 virtual void Verify() { } 3310 virtual void Verify() { }
3318 #endif 3311 #endif
3319 3312
3320 DECLARE_CONCRETE_INSTRUCTION(Constant) 3313 DECLARE_CONCRETE_INSTRUCTION(Constant)
3321 3314
3322 protected: 3315 protected:
3323 virtual Range* InferRange(Zone* zone); 3316 virtual Range* InferRange(Zone* zone);
3324 3317
3325 virtual bool DataEquals(HValue* other) { 3318 virtual bool DataEquals(HValue* other) {
3326 HConstant* other_constant = HConstant::cast(other); 3319 HConstant* other_constant = HConstant::cast(other);
3327 if (has_int32_value_) { 3320 if (has_int32_value_) {
3328 return other_constant->has_int32_value_ && 3321 return other_constant->has_int32_value_ &&
3329 int32_value_ == other_constant->int32_value_; 3322 int32_value_ == other_constant->int32_value_;
3330 } else if (has_double_value_) { 3323 } else if (has_double_value_) {
3331 return other_constant->has_double_value_ && 3324 return other_constant->has_double_value_ &&
3332 BitCast<int64_t>(double_value_) == 3325 BitCast<int64_t>(double_value_) ==
3333 BitCast<int64_t>(other_constant->double_value_); 3326 BitCast<int64_t>(other_constant->double_value_);
3334 } else { 3327 } else {
3335 ASSERT(!handle_.is_null()); 3328 ASSERT(!handle_.is_null());
3329 ASSERT_NE(NULL, raw_address_);
3336 return !other_constant->handle_.is_null() && 3330 return !other_constant->handle_.is_null() &&
3337 handle_.is_identical_to(other_constant->handle_); 3331 raw_address_ == other_constant->raw_address_;
3338 } 3332 }
3339 } 3333 }
3340 3334
3341 private: 3335 private:
3342 void Initialize(Representation r); 3336 void Initialize(Representation r);
3343 3337
3344 virtual bool IsDeletable() const { return true; } 3338 virtual bool IsDeletable() const { return true; }
3345 3339
3346 // If this is a numerical constant, handle_ either points to to the 3340 // If this is a numerical constant, handle_ either points to to the
3347 // HeapObject the constant originated from or is null. If the 3341 // HeapObject the constant originated from or is null. If the
3348 // constant is non-numeric, handle_ always points to a valid 3342 // constant is non-numeric, handle_ always points to a valid
3349 // constant HeapObject. 3343 // constant HeapObject.
3350 Handle<Object> handle_; 3344 Handle<Object> handle_;
3351 3345
3352 // We store the HConstant in the most specific form safely possible. 3346 // 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 3347 // The two flags, has_int32_value_ and has_double_value_ tell us if
3354 // int32_value_ and double_value_ hold valid, safe representations 3348 // int32_value_ and double_value_ hold valid, safe representations
3355 // of the constant. has_int32_value_ implies has_double_value_ but 3349 // of the constant. has_int32_value_ implies has_double_value_ but
3356 // not the converse. 3350 // not the converse.
3357 bool has_int32_value_ : 1; 3351 bool has_int32_value_ : 1;
3358 bool has_double_value_ : 1; 3352 bool has_double_value_ : 1;
3359 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. 3353 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
3360 bool boolean_value_ : 1; 3354 bool boolean_value_ : 1;
3361 int32_t int32_value_; 3355 // An extra hash code is only necessary if the value is not a number.
3356 // So has_double_value_ governs how to interpret the union.
3357 union {
3358 int32_t int32_value_;
3359 Address raw_address_;
3360 };
3362 double double_value_; 3361 double double_value_;
3363 HType type_from_value_; 3362 HType type_from_value_;
3364 }; 3363 };
3365 3364
3366 3365
3367 class HBinaryOperation: public HTemplateInstruction<3> { 3366 class HBinaryOperation: public HTemplateInstruction<3> {
3368 public: 3367 public:
3369 HBinaryOperation(HValue* context, HValue* left, HValue* right) 3368 HBinaryOperation(HValue* context, HValue* left, HValue* right)
3370 : observed_output_representation_(Representation::None()) { 3369 : observed_output_representation_(Representation::None()) {
3371 ASSERT(left != NULL && right != NULL); 3370 ASSERT(left != NULL && right != NULL);
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after
4752 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) 4751 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
4753 4752
4754 private: 4753 private:
4755 HPhi* incoming_value_; 4754 HPhi* incoming_value_;
4756 }; 4755 };
4757 4756
4758 4757
4759 class HLoadGlobalCell: public HTemplateInstruction<0> { 4758 class HLoadGlobalCell: public HTemplateInstruction<0> {
4760 public: 4759 public:
4761 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details) 4760 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details)
4762 : cell_(cell), details_(details) { 4761 : cell_(cell), details_(details), unique_id_(0) {
4763 set_representation(Representation::Tagged()); 4762 set_representation(Representation::Tagged());
4764 SetFlag(kUseGVN); 4763 SetFlag(kUseGVN);
4765 SetGVNFlag(kDependsOnGlobalVars); 4764 SetGVNFlag(kDependsOnGlobalVars);
4766 } 4765 }
4767 4766
4768 Handle<JSGlobalPropertyCell> cell() const { return cell_; } 4767 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
4769 bool RequiresHoleCheck() const; 4768 bool RequiresHoleCheck() const;
4770 4769
4771 virtual void PrintDataTo(StringStream* stream); 4770 virtual void PrintDataTo(StringStream* stream);
4772 4771
4773 virtual intptr_t Hashcode() { 4772 virtual intptr_t Hashcode() {
4774 ASSERT_ALLOCATION_DISABLED; 4773 ASSERT_NE(0, unique_id_);
4775 // Dereferencing to use the object's raw address for hashing is safe. 4774 return unique_id_;
4776 HandleDereferenceGuard allow_handle_deref(isolate(), 4775 }
4777 HandleDereferenceGuard::ALLOW); 4776
4778 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || 4777 virtual void FinalizeHashcode() {
4779 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); 4778 // Hash code has not been set, or already set to the same value.
4780 return reinterpret_cast<intptr_t>(*cell_); 4779 ASSERT(unique_id_ == 0 ||
4780 unique_id_ == reinterpret_cast<intptr_t>(*cell_));
4781 unique_id_ = reinterpret_cast<intptr_t>(*cell_);
4781 } 4782 }
4782 4783
4783 virtual Representation RequiredInputRepresentation(int index) { 4784 virtual Representation RequiredInputRepresentation(int index) {
4784 return Representation::None(); 4785 return Representation::None();
4785 } 4786 }
4786 4787
4787 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) 4788 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
4788 4789
4789 protected: 4790 protected:
4790 virtual bool DataEquals(HValue* other) { 4791 virtual bool DataEquals(HValue* other) {
4791 HLoadGlobalCell* b = HLoadGlobalCell::cast(other); 4792 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
4792 return cell_.is_identical_to(b->cell()); 4793 ASSERT_NE(0, unique_id_);
4794 return unique_id_ == b->unique_id_;
4793 } 4795 }
4794 4796
4795 private: 4797 private:
4796 virtual bool IsDeletable() const { return !RequiresHoleCheck(); } 4798 virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
4797 4799
4798 Handle<JSGlobalPropertyCell> cell_; 4800 Handle<JSGlobalPropertyCell> cell_;
4799 PropertyDetails details_; 4801 PropertyDetails details_;
4802 intptr_t unique_id_;
4800 }; 4803 };
4801 4804
4802 4805
4803 class HLoadGlobalGeneric: public HTemplateInstruction<2> { 4806 class HLoadGlobalGeneric: public HTemplateInstruction<2> {
4804 public: 4807 public:
4805 HLoadGlobalGeneric(HValue* context, 4808 HLoadGlobalGeneric(HValue* context,
4806 HValue* global_object, 4809 HValue* global_object,
4807 Handle<Object> name, 4810 Handle<Object> name,
4808 bool for_typeof) 4811 bool for_typeof)
4809 : name_(name), 4812 : name_(name),
(...skipping 1622 matching lines...) Expand 10 before | Expand all | Expand 10 after
6432 virtual bool IsDeletable() const { return true; } 6435 virtual bool IsDeletable() const { return true; }
6433 }; 6436 };
6434 6437
6435 6438
6436 #undef DECLARE_INSTRUCTION 6439 #undef DECLARE_INSTRUCTION
6437 #undef DECLARE_CONCRETE_INSTRUCTION 6440 #undef DECLARE_CONCRETE_INSTRUCTION
6438 6441
6439 } } // namespace v8::internal 6442 } } // namespace v8::internal
6440 6443
6441 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6444 #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