OLD | NEW |
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" |
(...skipping 6194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6205 friend class SideEffectsTracker; | 6205 friend class SideEffectsTracker; |
6206 | 6206 |
6207 inline Portion portion() const { | 6207 inline Portion portion() const { |
6208 return PortionField::decode(value_); | 6208 return PortionField::decode(value_); |
6209 } | 6209 } |
6210 }; | 6210 }; |
6211 | 6211 |
6212 | 6212 |
6213 class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { | 6213 class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { |
6214 public: | 6214 public: |
6215 static HLoadNamedField* New(Zone* zone, HValue* context, | 6215 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, |
6216 HValue* object, HValue* dependency, | 6216 HValue*, HObjectAccess); |
6217 HObjectAccess access) { | 6217 DECLARE_INSTRUCTION_FACTORY_P5(HLoadNamedField, HValue*, HValue*, |
6218 return new(zone) HLoadNamedField( | 6218 HObjectAccess, const UniqueSet<Map>*, HType); |
6219 object, dependency, access, new(zone) UniqueSet<Map>()); | |
6220 } | |
6221 static HLoadNamedField* New(Zone* zone, HValue* context, | |
6222 HValue* object, HValue* dependency, | |
6223 HObjectAccess access, SmallMapList* map_list, | |
6224 CompilationInfo* info) { | |
6225 UniqueSet<Map>* maps = new(zone) UniqueSet<Map>(map_list->length(), zone); | |
6226 for (int i = 0; i < map_list->length(); ++i) { | |
6227 Handle<Map> map = map_list->at(i); | |
6228 maps->Add(Unique<Map>::CreateImmovable(map), zone); | |
6229 // TODO(bmeurer): Get rid of this shit! | |
6230 if (map->CanTransition()) { | |
6231 Map::AddDependentCompilationInfo( | |
6232 map, DependentCode::kPrototypeCheckGroup, info); | |
6233 } | |
6234 } | |
6235 return new(zone) HLoadNamedField(object, dependency, access, maps); | |
6236 } | |
6237 | 6219 |
6238 HValue* object() { return OperandAt(0); } | 6220 HValue* object() { return OperandAt(0); } |
6239 HValue* dependency() { | 6221 HValue* dependency() { |
6240 ASSERT(HasDependency()); | 6222 ASSERT(HasDependency()); |
6241 return OperandAt(1); | 6223 return OperandAt(1); |
6242 } | 6224 } |
6243 bool HasDependency() const { return OperandAt(0) != OperandAt(1); } | 6225 bool HasDependency() const { return OperandAt(0) != OperandAt(1); } |
6244 HObjectAccess access() const { return access_; } | 6226 HObjectAccess access() const { return access_; } |
6245 Representation field_representation() const { | 6227 Representation field_representation() const { |
6246 return access_.representation(); | 6228 return access_.representation(); |
6247 } | 6229 } |
6248 | 6230 |
6249 const UniqueSet<Map>* maps() const { return maps_; } | 6231 const UniqueSet<Map>* maps() const { return maps_; } |
6250 | 6232 |
6251 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 6233 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
6252 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { | 6234 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { |
6253 return !access().IsInobject() || access().offset() >= size; | 6235 return !access().IsInobject() || access().offset() >= size; |
6254 } | 6236 } |
6255 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 6237 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
6256 if (index == 0 && access().IsExternalMemory()) { | 6238 if (index == 0 && access().IsExternalMemory()) { |
6257 // object must be external in case of external memory access | 6239 // object must be external in case of external memory access |
6258 return Representation::External(); | 6240 return Representation::External(); |
6259 } | 6241 } |
6260 return Representation::Tagged(); | 6242 return Representation::Tagged(); |
6261 } | 6243 } |
6262 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; | 6244 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; |
6263 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 6245 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
6264 | 6246 |
| 6247 bool CanBeReplacedWith(HValue* other) const { |
| 6248 if (!type().Equals(other->type())) return false; |
| 6249 if (!representation().Equals(other->representation())) return false; |
| 6250 if (!other->IsLoadNamedField()) return true; |
| 6251 HLoadNamedField* that = HLoadNamedField::cast(other); |
| 6252 if (this->maps_ == that->maps_) return true; |
| 6253 if (this->maps_ == NULL || that->maps_ == NULL) return false; |
| 6254 return this->maps_->IsSubset(that->maps_); |
| 6255 } |
| 6256 |
6265 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 6257 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
6266 | 6258 |
6267 protected: | 6259 protected: |
6268 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 6260 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
6269 HLoadNamedField* b = HLoadNamedField::cast(other); | 6261 HLoadNamedField* that = HLoadNamedField::cast(other); |
6270 return access_.Equals(b->access_) && this->maps()->Equals(b->maps()); | 6262 if (!this->access_.Equals(that->access_)) return false; |
| 6263 if (this->maps_ == that->maps_) return true; |
| 6264 return (this->maps_ != NULL && |
| 6265 that->maps_ != NULL && |
| 6266 this->maps_->Equals(that->maps_)); |
6271 } | 6267 } |
6272 | 6268 |
6273 private: | 6269 private: |
6274 HLoadNamedField(HValue* object, | 6270 HLoadNamedField(HValue* object, |
6275 HValue* dependency, | 6271 HValue* dependency, |
6276 HObjectAccess access, | 6272 HObjectAccess access) |
6277 const UniqueSet<Map>* maps) | 6273 : access_(access), maps_(NULL) { |
6278 : access_(access), maps_(maps) { | 6274 ASSERT_NOT_NULL(object); |
6279 ASSERT(object != NULL); | |
6280 SetOperandAt(0, object); | 6275 SetOperandAt(0, object); |
6281 SetOperandAt(1, dependency != NULL ? dependency : object); | 6276 SetOperandAt(1, dependency ? dependency : object); |
6282 | 6277 |
6283 Representation representation = access.representation(); | 6278 Representation representation = access.representation(); |
6284 if (representation.IsInteger8() || | 6279 if (representation.IsInteger8() || |
6285 representation.IsUInteger8() || | 6280 representation.IsUInteger8() || |
6286 representation.IsInteger16() || | 6281 representation.IsInteger16() || |
6287 representation.IsUInteger16()) { | 6282 representation.IsUInteger16()) { |
6288 set_representation(Representation::Integer32()); | 6283 set_representation(Representation::Integer32()); |
6289 } else if (representation.IsSmi()) { | 6284 } else if (representation.IsSmi()) { |
6290 set_type(HType::Smi()); | 6285 set_type(HType::Smi()); |
6291 if (SmiValuesAre32Bits()) { | 6286 if (SmiValuesAre32Bits()) { |
6292 set_representation(Representation::Integer32()); | 6287 set_representation(Representation::Integer32()); |
6293 } else { | 6288 } else { |
6294 set_representation(representation); | 6289 set_representation(representation); |
6295 } | 6290 } |
6296 } else if (representation.IsDouble() || | 6291 } else if (representation.IsDouble() || |
6297 representation.IsExternal() || | 6292 representation.IsExternal() || |
6298 representation.IsInteger32()) { | 6293 representation.IsInteger32()) { |
6299 set_representation(representation); | 6294 set_representation(representation); |
6300 } else if (representation.IsHeapObject()) { | 6295 } else if (representation.IsHeapObject()) { |
| 6296 // TODO(bmeurer): This is probably broken. What we actually want to to |
| 6297 // instead is set_representation(Representation::HeapObject()). |
6301 set_type(HType::NonPrimitive()); | 6298 set_type(HType::NonPrimitive()); |
6302 set_representation(Representation::Tagged()); | 6299 set_representation(Representation::Tagged()); |
6303 } else { | 6300 } else { |
6304 set_representation(Representation::Tagged()); | 6301 set_representation(Representation::Tagged()); |
6305 } | 6302 } |
6306 access.SetGVNFlags(this, LOAD); | 6303 access.SetGVNFlags(this, LOAD); |
6307 } | 6304 } |
6308 | 6305 |
| 6306 HLoadNamedField(HValue* object, |
| 6307 HValue* dependency, |
| 6308 HObjectAccess access, |
| 6309 const UniqueSet<Map>* maps, |
| 6310 HType type) |
| 6311 : HTemplateInstruction<2>(type), access_(access), maps_(maps) { |
| 6312 ASSERT_NOT_NULL(maps); |
| 6313 ASSERT_NE(0, maps->size()); |
| 6314 |
| 6315 ASSERT_NOT_NULL(object); |
| 6316 SetOperandAt(0, object); |
| 6317 SetOperandAt(1, dependency ? dependency : object); |
| 6318 |
| 6319 ASSERT(access.representation().IsHeapObject()); |
| 6320 // TODO(bmeurer): This is probably broken. What we actually want to to |
| 6321 // instead is set_representation(Representation::HeapObject()). |
| 6322 if (!type.IsHeapObject()) set_type(HType::NonPrimitive()); |
| 6323 set_representation(Representation::Tagged()); |
| 6324 |
| 6325 access.SetGVNFlags(this, LOAD); |
| 6326 } |
| 6327 |
6309 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 6328 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
6310 | 6329 |
6311 HObjectAccess access_; | 6330 HObjectAccess access_; |
6312 const UniqueSet<Map>* maps_; | 6331 const UniqueSet<Map>* maps_; |
6313 }; | 6332 }; |
6314 | 6333 |
6315 | 6334 |
6316 class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> { | 6335 class HLoadNamedGeneric V8_FINAL : public HTemplateInstruction<2> { |
6317 public: | 6336 public: |
6318 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HLoadNamedGeneric, HValue*, | 6337 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HLoadNamedGeneric, HValue*, |
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7632 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7651 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
7633 }; | 7652 }; |
7634 | 7653 |
7635 | 7654 |
7636 #undef DECLARE_INSTRUCTION | 7655 #undef DECLARE_INSTRUCTION |
7637 #undef DECLARE_CONCRETE_INSTRUCTION | 7656 #undef DECLARE_CONCRETE_INSTRUCTION |
7638 | 7657 |
7639 } } // namespace v8::internal | 7658 } } // namespace v8::internal |
7640 | 7659 |
7641 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7660 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |