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

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

Issue 11365174: A change in the way we place TransitionElementKinds in the tree. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Now have instruction writing, map check updating. Created 8 years 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
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 2240 matching lines...) Expand 10 before | Expand all | Expand 10 after
2251 } 2251 }
2252 2252
2253 virtual Representation RequiredInputRepresentation(int index) { 2253 virtual Representation RequiredInputRepresentation(int index) {
2254 return Representation::Tagged(); 2254 return Representation::Tagged();
2255 } 2255 }
2256 2256
2257 virtual void PrintDataTo(StringStream* stream); 2257 virtual void PrintDataTo(StringStream* stream);
2258 virtual HType CalculateInferredType(); 2258 virtual HType CalculateInferredType();
2259 2259
2260 HValue* value() { return OperandAt(0); } 2260 HValue* value() { return OperandAt(0); }
2261 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
2262 void RemoveTypeCheck() { SetOperandAt(1, OperandAt(0)); }
2261 SmallMapList* map_set() { return &map_set_; } 2263 SmallMapList* map_set() { return &map_set_; }
2262 CompareMapMode mode() { return mode_; } 2264 CompareMapMode mode() { return mode_; }
2263 2265
2264 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) 2266 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
2265 2267
2266 protected: 2268 protected:
2267 virtual bool DataEquals(HValue* other) { 2269 virtual bool DataEquals(HValue* other) {
2268 HCheckMaps* b = HCheckMaps::cast(other); 2270 HCheckMaps* b = HCheckMaps::cast(other);
2269 // Relies on the fact that map_set has been sorted before. 2271 // Relies on the fact that map_set has been sorted before.
2270 if (map_set()->length() != b->map_set()->length()) return false; 2272 if (map_set()->length() != b->map_set()->length()) return false;
(...skipping 2052 matching lines...) Expand 10 before | Expand all | Expand 10 after
4323 virtual Representation RequiredInputRepresentation(int index) { 4325 virtual Representation RequiredInputRepresentation(int index) {
4324 return Representation::Tagged(); 4326 return Representation::Tagged();
4325 } 4327 }
4326 4328
4327 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) 4329 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
4328 4330
4329 protected: 4331 protected:
4330 virtual bool DataEquals(HValue* other) { return true; } 4332 virtual bool DataEquals(HValue* other) { return true; }
4331 }; 4333 };
4332 4334
4333 class ArrayInstructionInterface { 4335
4336 class HTransitionElementsKind;
4337 class TransitionElementsBookmark BASE_EMBEDDED {
4334 public: 4338 public:
4335 virtual HValue* GetKey() = 0; 4339 TransitionElementsBookmark(HTransitionElementsKind* transition,
4336 virtual void SetKey(HValue* key) = 0; 4340 Handle<Map> map_from,
4341 Handle<Map> map_to,
4342 Isolate* isolate);
4343 ElementsKind elementskind_from() const { return from_->elements_kind(); }
4344 ElementsKind elementskind_to() const { return to_->elements_kind(); }
4345 Handle<Map> from() const { return from_; }
4346 Handle<Map>* from_pointer() { return &from_; }
4347 Handle<Map> to() const { return to_; }
4348 Handle<Map>* to_pointer() { return &to_; }
4349 Handle<Map> family() const { return family_; }
4350 Handle<Map>* family_pointer() { return &family_; }
4351 Handle<Map> pessimistic_holey() const { return pessimistic_holey_; }
4352 Handle<Map>* pessimistic_holey_pointer() { return &pessimistic_holey_; }
4353 HTransitionElementsKind* transition_instruction() const {
4354 return transition_; }
4355
4356 bool Equals(const TransitionElementsBookmark& other) const {
4357 return *from() == *(other.from()) &&
4358 *to() == *(other.to()) &&
4359 *family() == *(other.family());
4360 }
4361
4362 private:
4363 HTransitionElementsKind* transition_;
4364 Handle<Map> from_;
4365 Handle<Map> to_;
4366 Handle<Map> family_;
4367 Handle<Map> pessimistic_holey_;
4368 };
4369
4370
4371 class ArrayInstruction: public HTemplateInstruction<3> {
4372 public:
4373 ArrayInstruction(HValue* obj, HValue* key, Zone* zone) :
4374 zone_(zone),
4375 bookmarks_(new(zone) ZoneList<TransitionElementsBookmark>(10, zone)),
4376 hoistable_(true) {
4377 SetOperandAt(0, obj);
4378 SetOperandAt(1, key);
4379
4380 #ifdef DEBUG
4381 initialized_ = false;
4382 #endif
4383 }
4384
4385 HValue* elements() { return OperandAt(0); }
4386 HValue* key() { return OperandAt(1); }
4387
4388 HValue* GetKey() { return key(); }
4389 void SetKey(HValue* key) { SetOperandAt(1, key); }
4390
4391 #ifdef DEBUG
4392 bool Initialized() const { return initialized_; }
4393 void SetInitialized() { initialized_ = true; }
4394 #endif
4395
4337 virtual void SetIndexOffset(uint32_t index_offset) = 0; 4396 virtual void SetIndexOffset(uint32_t index_offset) = 0;
4338 virtual bool IsDehoisted() = 0; 4397 virtual bool IsDehoisted() = 0;
4339 virtual void SetDehoisted(bool is_dehoisted) = 0; 4398 virtual void SetDehoisted(bool is_dehoisted) = 0;
4340 virtual ~ArrayInstructionInterface() { }; 4399 virtual void PerformDeferredInitialization(
4400 ElementsKind new_elements_kind) = 0;
4401 virtual void PerformDeferredInitialization() = 0;
4402 virtual ~ArrayInstruction() { };
4403
4404 void AddBookmarks(const ZoneList<TransitionElementsBookmark>& records);
4405 bool hoistable() const { return hoistable_; }
4406 void set_hoistable(bool value) { hoistable_ = value; }
4407
4408 int bookmarks() const { return bookmarks_->length(); }
4409 TransitionElementsBookmark* bookmark(int index) {
4410 return &(bookmarks_->at(index));
4411 }
4412
4413 Map* map_family();
4414
4415 void Finalize(ElementsKind kind) {
4416 // ElementsKind elements_kind = most_general_map()->elements_kind();
4417 PerformDeferredInitialization(kind);
4418 }
4419
4420 void Finalize() {
4421 // ElementsKind elements_kind = most_general_map()->elements_kind();
4422 PerformDeferredInitialization();
4423 }
4424
4425 void PrintElementPlacementTo(StringStream* stream);
4426
4427 private:
4428 Zone* zone_;
4429 ZoneList<TransitionElementsBookmark>* bookmarks_;
4430 bool hoistable_;
4431 #ifdef DEBUG
4432 bool initialized_;
4433 #endif
4341 }; 4434 };
4342 4435
4343 4436
4344 class HLoadKeyed 4437 class HLoadKeyed
4345 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 4438 : public ArrayInstruction {
4346 public: 4439 public:
4347 HLoadKeyed(HValue* obj, 4440 HLoadKeyed(HValue* obj,
4348 HValue* key, 4441 HValue* key,
4349 HValue* dependency, 4442 HValue* dependency,
4350 ElementsKind elements_kind) 4443 ElementsKind elements_kind,
4351 : bit_field_(0) { 4444 Zone* zone)
4445 : ArrayInstruction(obj, key, zone), bit_field_(0) {
4352 bit_field_ = ElementsKindField::encode(elements_kind); 4446 bit_field_ = ElementsKindField::encode(elements_kind);
4353 4447
4354 SetOperandAt(0, obj);
4355 SetOperandAt(1, key);
4356 SetOperandAt(2, dependency); 4448 SetOperandAt(2, dependency);
4357 4449
4358 if (!is_external()) { 4450 if (is_external()) {
4359 // I can detect the case between storing double (holey and fast) and
4360 // smi/object by looking at elements_kind_.
4361 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
4362 IsFastDoubleElementsKind(elements_kind));
4363
4364 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
4365 if (IsFastSmiElementsKind(elements_kind) &&
4366 IsFastPackedElementsKind(elements_kind)) {
4367 set_type(HType::Smi());
4368 }
4369
4370 set_representation(Representation::Tagged());
4371 SetGVNFlag(kDependsOnArrayElements);
4372 } else {
4373 set_representation(Representation::Double());
4374 SetGVNFlag(kDependsOnDoubleArrayElements);
4375 }
4376 } else {
4377 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4451 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
4378 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4452 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4379 set_representation(Representation::Double()); 4453 set_representation(Representation::Double());
4380 } else { 4454 } else {
4381 set_representation(Representation::Integer32()); 4455 set_representation(Representation::Integer32());
4382 } 4456 }
4383 4457
4384 SetGVNFlag(kDependsOnSpecializedArrayElements); 4458 SetGVNFlag(kDependsOnSpecializedArrayElements);
4385 // Native code could change the specialized array. 4459 // Native code could change the specialized array.
4386 SetGVNFlag(kDependsOnCalls); 4460 SetGVNFlag(kDependsOnCalls);
4461 } else {
4462 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
4463 IsFastDoubleElementsKind(elements_kind));
4464
4465 // We don't yet know what it depends on yet, so set both flags
4466 SetGVNFlag(kDependsOnArrayElements);
4467 SetGVNFlag(kDependsOnDoubleArrayElements);
4468 }
4469
4470 SetFlag(kUseGVN);
4471
4472 if (!FLAG_use_place_elements_transitions) {
4473 PerformDeferredInitialization();
4474 }
4475 }
4476
4477
4478 void PerformDeferredInitialization(ElementsKind new_elements_kind) {
4479 #ifdef DEBUG
4480 ASSERT(!Initialized());
4481 SetInitialized();
4482 #endif
4483 if (new_elements_kind != elements_kind()) {
4484 bit_field_ = ElementsKindField::encode(new_elements_kind);
4387 } 4485 }
4388 4486
4389 SetFlag(kUseGVN); 4487 ClearGVNFlag(kDependsOnArrayElements);
4488 ClearGVNFlag(kDependsOnDoubleArrayElements);
4489
4490 if (IsFastSmiOrObjectElementsKind(elements_kind())) {
4491 if (IsFastSmiElementsKind(elements_kind()) &&
4492 IsFastPackedElementsKind(elements_kind())) {
4493 set_type(HType::Smi());
4494 }
4495
4496 set_representation(Representation::Tagged());
4497 SetGVNFlag(kDependsOnArrayElements);
4498 } else {
4499 set_representation(Representation::Double());
4500 SetGVNFlag(kDependsOnDoubleArrayElements);
4501 }
4390 } 4502 }
4391 4503
4504 void PerformDeferredInitialization() {
4505 PerformDeferredInitialization(elements_kind());
4506 }
4507
4392 bool is_external() const { 4508 bool is_external() const {
4393 return IsExternalArrayElementsKind(elements_kind()); 4509 return IsExternalArrayElementsKind(elements_kind());
4394 } 4510 }
4395 HValue* elements() { return OperandAt(0); }
4396 HValue* key() { return OperandAt(1); }
4397 HValue* dependency() { return OperandAt(2); } 4511 HValue* dependency() { return OperandAt(2); }
4398 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } 4512 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4399 void SetIndexOffset(uint32_t index_offset) { 4513 void SetIndexOffset(uint32_t index_offset) {
4400 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); 4514 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4401 } 4515 }
4402 HValue* GetKey() { return key(); }
4403 void SetKey(HValue* key) { SetOperandAt(1, key); }
4404 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } 4516 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4405 void SetDehoisted(bool is_dehoisted) { 4517 void SetDehoisted(bool is_dehoisted) {
4406 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); 4518 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4407 } 4519 }
4408 ElementsKind elements_kind() const { 4520 ElementsKind elements_kind() const {
4409 return ElementsKindField::decode(bit_field_); 4521 return ElementsKindField::decode(bit_field_);
4410 } 4522 }
4411 4523
4412 virtual Representation RequiredInputRepresentation(int index) { 4524 virtual Representation RequiredInputRepresentation(int index) {
4525 ASSERT(Initialized());
4526
4413 // kind_fast: tagged[int32] (none) 4527 // kind_fast: tagged[int32] (none)
4414 // kind_double: tagged[int32] (none) 4528 // kind_double: tagged[int32] (none)
4415 // kind_external: external[int32] (none) 4529 // kind_external: external[int32] (none)
4416 if (index == 0) { 4530 if (index == 0) {
4417 return is_external() ? Representation::External() 4531 return is_external() ? Representation::External()
4418 : Representation::Tagged(); 4532 : Representation::Tagged();
4419 } 4533 }
4420 if (index == 1) return Representation::Integer32(); 4534 if (index == 1) return Representation::Integer32();
4421 return Representation::None(); 4535 return Representation::None();
4422 } 4536 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
4592 4706
4593 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) 4707 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
4594 4708
4595 private: 4709 private:
4596 Handle<String> name_; 4710 Handle<String> name_;
4597 StrictModeFlag strict_mode_flag_; 4711 StrictModeFlag strict_mode_flag_;
4598 }; 4712 };
4599 4713
4600 4714
4601 class HStoreKeyed 4715 class HStoreKeyed
4602 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 4716 : public ArrayInstruction {
4603 public: 4717 public:
4604 HStoreKeyed(HValue* obj, HValue* key, HValue* val, 4718 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
4605 ElementsKind elements_kind) 4719 ElementsKind elements_kind,
4606 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { 4720 Zone* zone)
4607 SetOperandAt(0, obj); 4721 : ArrayInstruction(obj, key, zone),
4608 SetOperandAt(1, key); 4722 elements_kind_(elements_kind),
4723 index_offset_(0),
4724 is_dehoisted_(false) {
4609 SetOperandAt(2, val); 4725 SetOperandAt(2, val);
4610 4726
4611 if (is_external()) { 4727 if (is_external()) {
4612 SetGVNFlag(kChangesSpecializedArrayElements); 4728 SetGVNFlag(kChangesSpecializedArrayElements);
4613 } else if (IsFastDoubleElementsKind(elements_kind)) { 4729 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
4730 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
4731 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
4732 SetFlag(kTruncatingToInt32);
4733 }
4734 } else {
4735 // We don't know what we'll have later.
4736 // Initialize for the worst case
4614 SetGVNFlag(kChangesDoubleArrayElements); 4737 SetGVNFlag(kChangesDoubleArrayElements);
4615 SetFlag(kDeoptimizeOnUndefined); 4738 SetFlag(kDeoptimizeOnUndefined);
4616 } else {
4617 SetGVNFlag(kChangesArrayElements); 4739 SetGVNFlag(kChangesArrayElements);
4618 } 4740 }
4619 4741
4620 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 4742 if (!FLAG_use_place_elements_transitions) {
4621 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && 4743 PerformDeferredInitialization();
4622 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
4623 SetFlag(kTruncatingToInt32);
4624 } 4744 }
4625 } 4745 }
4626 4746
4747 void PerformDeferredInitialization(ElementsKind new_elements_kind) {
4748 #ifdef DEBUG
4749 ASSERT(!Initialized());
4750 SetInitialized();
4751 #endif
4752 if (new_elements_kind != elements_kind_) {
4753 elements_kind_ = new_elements_kind;
4754 }
4755
4756 // Adjust flags appropriately
4757 if (IsFastDoubleElementsKind(elements_kind())) {
4758 ClearGVNFlag(kChangesArrayElements);
4759 } else {
4760 ClearGVNFlag(kChangesDoubleArrayElements);
4761 ClearFlag(kDeoptimizeOnUndefined);
4762 }
4763 }
4764
4765 void PerformDeferredInitialization() {
4766 PerformDeferredInitialization(elements_kind());
4767 }
4768
4627 virtual Representation RequiredInputRepresentation(int index) { 4769 virtual Representation RequiredInputRepresentation(int index) {
4770 ASSERT(Initialized());
4628 // kind_fast: tagged[int32] = tagged 4771 // kind_fast: tagged[int32] = tagged
4629 // kind_double: tagged[int32] = double 4772 // kind_double: tagged[int32] = double
4630 // kind_external: external[int32] = (double | int32) 4773 // kind_external: external[int32] = (double | int32)
4631 if (index == 0) { 4774 if (index == 0) {
4632 return is_external() ? Representation::External() 4775 return is_external() ? Representation::External()
4633 : Representation::Tagged(); 4776 : Representation::Tagged();
4634 } else if (index == 1) { 4777 } else if (index == 1) {
4635 return Representation::Integer32(); 4778 return Representation::Integer32();
4636 } 4779 }
4637 4780
(...skipping 15 matching lines...) Expand all
4653 if (IsDoubleOrFloatElementsKind(elements_kind())) { 4796 if (IsDoubleOrFloatElementsKind(elements_kind())) {
4654 return Representation::Double(); 4797 return Representation::Double();
4655 } 4798 }
4656 if (is_external()) { 4799 if (is_external()) {
4657 return Representation::Integer32(); 4800 return Representation::Integer32();
4658 } 4801 }
4659 // For fast object elements kinds, don't assume anything. 4802 // For fast object elements kinds, don't assume anything.
4660 return Representation::None(); 4803 return Representation::None();
4661 } 4804 }
4662 4805
4663 HValue* elements() { return OperandAt(0); }
4664 HValue* key() { return OperandAt(1); }
4665 HValue* value() { return OperandAt(2); } 4806 HValue* value() { return OperandAt(2); }
4666 bool value_is_smi() const { 4807 bool value_is_smi() const {
4667 return IsFastSmiElementsKind(elements_kind_); 4808 return IsFastSmiElementsKind(elements_kind_);
4668 } 4809 }
4669 ElementsKind elements_kind() const { return elements_kind_; } 4810 ElementsKind elements_kind() const { return elements_kind_; }
4670 uint32_t index_offset() { return index_offset_; } 4811 uint32_t index_offset() { return index_offset_; }
4671 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4812 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4672 HValue* GetKey() { return key(); }
4673 void SetKey(HValue* key) { SetOperandAt(1, key); }
4674 bool IsDehoisted() { return is_dehoisted_; } 4813 bool IsDehoisted() { return is_dehoisted_; }
4675 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4814 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4676 4815
4677 bool NeedsWriteBarrier() { 4816 bool NeedsWriteBarrier() {
4678 if (value_is_smi()) { 4817 if (value_is_smi()) {
4679 return false; 4818 return false;
4680 } else { 4819 } else {
4681 return StoringValueNeedsWriteBarrier(value()); 4820 return StoringValueNeedsWriteBarrier(value());
4682 } 4821 }
4683 } 4822 }
4684 4823
4685 bool NeedsCanonicalization(); 4824 bool NeedsCanonicalization();
4686
4687 virtual void PrintDataTo(StringStream* stream); 4825 virtual void PrintDataTo(StringStream* stream);
4688 4826
4689 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) 4827 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
4690 4828
4691 private: 4829 private:
4692 ElementsKind elements_kind_; 4830 ElementsKind elements_kind_;
4693 uint32_t index_offset_; 4831 uint32_t index_offset_;
4694 bool is_dehoisted_; 4832 bool is_dehoisted_;
4695 }; 4833 };
4696 4834
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
5390 virtual bool IsDeletable() const { return true; } 5528 virtual bool IsDeletable() const { return true; }
5391 }; 5529 };
5392 5530
5393 5531
5394 #undef DECLARE_INSTRUCTION 5532 #undef DECLARE_INSTRUCTION
5395 #undef DECLARE_CONCRETE_INSTRUCTION 5533 #undef DECLARE_CONCRETE_INSTRUCTION
5396 5534
5397 } } // namespace v8::internal 5535 } } // namespace v8::internal
5398 5536
5399 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5537 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« src/hydrogen.cc ('K') | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698