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

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: Finally addressed all comments from first review. Created 8 years, 1 month 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 2238 matching lines...) Expand 10 before | Expand all | Expand 10 after
2249 } 2249 }
2250 2250
2251 virtual Representation RequiredInputRepresentation(int index) { 2251 virtual Representation RequiredInputRepresentation(int index) {
2252 return Representation::Tagged(); 2252 return Representation::Tagged();
2253 } 2253 }
2254 2254
2255 virtual void PrintDataTo(StringStream* stream); 2255 virtual void PrintDataTo(StringStream* stream);
2256 virtual HType CalculateInferredType(); 2256 virtual HType CalculateInferredType();
2257 2257
2258 HValue* value() { return OperandAt(0); } 2258 HValue* value() { return OperandAt(0); }
2259 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
2260 void RemoveTypeCheck() { SetOperandAt(1, OperandAt(0)); }
2259 SmallMapList* map_set() { return &map_set_; } 2261 SmallMapList* map_set() { return &map_set_; }
2260 2262
2261 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) 2263 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
2262 2264
2263 protected: 2265 protected:
2264 virtual bool DataEquals(HValue* other) { 2266 virtual bool DataEquals(HValue* other) {
2265 HCheckMaps* b = HCheckMaps::cast(other); 2267 HCheckMaps* b = HCheckMaps::cast(other);
2266 // Relies on the fact that map_set has been sorted before. 2268 // Relies on the fact that map_set has been sorted before.
2267 if (map_set()->length() != b->map_set()->length()) return false; 2269 if (map_set()->length() != b->map_set()->length()) return false;
2268 for (int i = 0; i < map_set()->length(); i++) { 2270 for (int i = 0; i < map_set()->length(); i++) {
(...skipping 2057 matching lines...) Expand 10 before | Expand all | Expand 10 after
4326 virtual bool DataEquals(HValue* other) { return true; } 4328 virtual bool DataEquals(HValue* other) { return true; }
4327 }; 4329 };
4328 4330
4329 class ArrayInstructionInterface { 4331 class ArrayInstructionInterface {
4330 public: 4332 public:
4331 virtual HValue* GetKey() = 0; 4333 virtual HValue* GetKey() = 0;
4332 virtual void SetKey(HValue* key) = 0; 4334 virtual void SetKey(HValue* key) = 0;
4333 virtual void SetIndexOffset(uint32_t index_offset) = 0; 4335 virtual void SetIndexOffset(uint32_t index_offset) = 0;
4334 virtual bool IsDehoisted() = 0; 4336 virtual bool IsDehoisted() = 0;
4335 virtual void SetDehoisted(bool is_dehoisted) = 0; 4337 virtual void SetDehoisted(bool is_dehoisted) = 0;
4338 virtual void PerformDeferredInitialization(
4339 ElementsKind new_elements_kind) = 0;
4336 virtual ~ArrayInstructionInterface() { }; 4340 virtual ~ArrayInstructionInterface() { };
4337 }; 4341 };
4338 4342
4339 4343
4340 class HLoadKeyed 4344 class HLoadKeyed
4341 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 4345 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4342 public: 4346 public:
4343 HLoadKeyed(HValue* obj, 4347 HLoadKeyed(HValue* obj,
4344 HValue* key, 4348 HValue* key,
4345 HValue* dependency, 4349 HValue* dependency,
4346 ElementsKind elements_kind) 4350 ElementsKind elements_kind,
4351 bool defer_initialization = false)
4347 : bit_field_(0) { 4352 : bit_field_(0) {
4348 bit_field_ = ElementsKindField::encode(elements_kind); 4353 bit_field_ = ElementsKindField::encode(elements_kind);
4349 4354
4355 #ifdef DEBUG
4356 initialized_ = !defer_initialization;
danno 2012/11/28 14:42:10 Make this transparent with a single macro in Array
mvstanton 2012/12/04 11:39:58 Done.
4357
4358 // Deferred initialization should only be invoked for fast elements
4359 // that are not external.
4360 ASSERT(!(defer_initialization && is_external()));
4361 #endif
4362
4350 SetOperandAt(0, obj); 4363 SetOperandAt(0, obj);
4351 SetOperandAt(1, key); 4364 SetOperandAt(1, key);
4352 SetOperandAt(2, dependency); 4365 SetOperandAt(2, dependency);
4353 4366
4354 if (!is_external()) { 4367 if (is_external()) {
4368 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
4369 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4370 set_representation(Representation::Double());
4371 } else {
4372 set_representation(Representation::Integer32());
4373 }
4374
4375 SetGVNFlag(kDependsOnSpecializedArrayElements);
4376 // Native code could change the specialized array.
4377 SetGVNFlag(kDependsOnCalls);
4378 } else if (defer_initialization) {
4379 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
4380 IsFastDoubleElementsKind(elements_kind));
4381
4382 // We don't yet know what it depends on yet, so set both flags
4383 SetGVNFlag(kDependsOnArrayElements);
4384 SetGVNFlag(kDependsOnDoubleArrayElements);
4385 } else {
4355 // I can detect the case between storing double (holey and fast) and 4386 // I can detect the case between storing double (holey and fast) and
4356 // smi/object by looking at elements_kind_. 4387 // smi/object by looking at elements_kind_.
4357 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || 4388 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
4358 IsFastDoubleElementsKind(elements_kind)); 4389 IsFastDoubleElementsKind(elements_kind));
4359 4390
4360 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 4391 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
4361 if (IsFastSmiElementsKind(elements_kind) && 4392 if (IsFastSmiElementsKind(elements_kind) &&
4362 IsFastPackedElementsKind(elements_kind)) { 4393 IsFastPackedElementsKind(elements_kind)) {
4363 set_type(HType::Smi()); 4394 set_type(HType::Smi());
4364 } 4395 }
4365 4396
4366 set_representation(Representation::Tagged()); 4397 set_representation(Representation::Tagged());
4367 SetGVNFlag(kDependsOnArrayElements); 4398 SetGVNFlag(kDependsOnArrayElements);
4368 } else { 4399 } else {
4369 set_representation(Representation::Double()); 4400 set_representation(Representation::Double());
4370 SetGVNFlag(kDependsOnDoubleArrayElements); 4401 SetGVNFlag(kDependsOnDoubleArrayElements);
4371 } 4402 }
4372 } else {
4373 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
4374 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4375 set_representation(Representation::Double());
4376 } else {
4377 set_representation(Representation::Integer32());
4378 }
4379
4380 SetGVNFlag(kDependsOnSpecializedArrayElements);
4381 // Native code could change the specialized array.
4382 SetGVNFlag(kDependsOnCalls);
4383 } 4403 }
4384 4404
4385 SetFlag(kUseGVN); 4405 SetFlag(kUseGVN);
4386 } 4406 }
4387 4407
4408 #ifdef DEBUG
4409 bool Initialized() const { return initialized_; }
4410 #endif
4411
4412 void PerformDeferredInitialization(ElementsKind new_elements_kind) {
danno 2012/11/28 14:42:10 Put this in the .cc
mvstanton 2012/12/04 11:39:58 Done.
4413 #ifdef DEBUG
4414 ASSERT(!initialized_);
4415 initialized_ = true;
4416 #endif
4417 if (new_elements_kind != elements_kind()) {
4418 bit_field_ = ElementsKindField::encode(new_elements_kind);
4419 }
4420
4421 // Start fresh
4422 ClearGVNFlag(kDependsOnArrayElements);
4423 ClearGVNFlag(kDependsOnDoubleArrayElements);
4424
4425 if (IsFastSmiOrObjectElementsKind(elements_kind())) {
4426 if (IsFastSmiElementsKind(elements_kind()) &&
4427 IsFastPackedElementsKind(elements_kind())) {
4428 set_type(HType::Smi());
4429 }
4430
4431 set_representation(Representation::Tagged());
4432 SetGVNFlag(kDependsOnArrayElements);
4433 } else {
4434 set_representation(Representation::Double());
4435 SetGVNFlag(kDependsOnDoubleArrayElements);
4436 }
4437 }
4438
4388 bool is_external() const { 4439 bool is_external() const {
4389 return IsExternalArrayElementsKind(elements_kind()); 4440 return IsExternalArrayElementsKind(elements_kind());
4390 } 4441 }
4391 HValue* elements() { return OperandAt(0); } 4442 HValue* elements() { return OperandAt(0); }
4392 HValue* key() { return OperandAt(1); } 4443 HValue* key() { return OperandAt(1); }
4393 HValue* dependency() { return OperandAt(2); } 4444 HValue* dependency() { return OperandAt(2); }
4394 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } 4445 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4395 void SetIndexOffset(uint32_t index_offset) { 4446 void SetIndexOffset(uint32_t index_offset) {
4396 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); 4447 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4397 } 4448 }
4398 HValue* GetKey() { return key(); } 4449 HValue* GetKey() { return key(); }
4399 void SetKey(HValue* key) { SetOperandAt(1, key); } 4450 void SetKey(HValue* key) { SetOperandAt(1, key); }
4400 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } 4451 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4401 void SetDehoisted(bool is_dehoisted) { 4452 void SetDehoisted(bool is_dehoisted) {
4402 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); 4453 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4403 } 4454 }
4404 ElementsKind elements_kind() const { 4455 ElementsKind elements_kind() const {
4405 return ElementsKindField::decode(bit_field_); 4456 return ElementsKindField::decode(bit_field_);
4406 } 4457 }
4407 4458
4408 virtual Representation RequiredInputRepresentation(int index) { 4459 virtual Representation RequiredInputRepresentation(int index) {
4460 #ifdef DEBUG
4461 // The idea here is that nobody should be inquiring about input
4462 // representation until we've finished a possibly deferred initialization
4463 ASSERT(initialized_);
4464 #endif
4409 // kind_fast: tagged[int32] (none) 4465 // kind_fast: tagged[int32] (none)
4410 // kind_double: tagged[int32] (none) 4466 // kind_double: tagged[int32] (none)
4411 // kind_external: external[int32] (none) 4467 // kind_external: external[int32] (none)
4412 if (index == 0) { 4468 if (index == 0) {
4413 return is_external() ? Representation::External() 4469 return is_external() ? Representation::External()
4414 : Representation::Tagged(); 4470 : Representation::Tagged();
4415 } 4471 }
4416 if (index == 1) return Representation::Integer32(); 4472 if (index == 1) return Representation::Integer32();
4417 return Representation::None(); 4473 return Representation::None();
4418 } 4474 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4461 class ElementsKindField: 4517 class ElementsKindField:
4462 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> 4518 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind>
4463 {}; // NOLINT 4519 {}; // NOLINT
4464 class IndexOffsetField: 4520 class IndexOffsetField:
4465 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> 4521 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset>
4466 {}; // NOLINT 4522 {}; // NOLINT
4467 class IsDehoistedField: 4523 class IsDehoistedField:
4468 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> 4524 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted>
4469 {}; // NOLINT 4525 {}; // NOLINT
4470 uint32_t bit_field_; 4526 uint32_t bit_field_;
4527 #ifdef DEBUG
4528 bool initialized_;
4529 #endif
4471 }; 4530 };
4472 4531
4473 4532
4474 class HLoadKeyedGeneric: public HTemplateInstruction<3> { 4533 class HLoadKeyedGeneric: public HTemplateInstruction<3> {
4475 public: 4534 public:
4476 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { 4535 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
4477 set_representation(Representation::Tagged()); 4536 set_representation(Representation::Tagged());
4478 SetOperandAt(0, obj); 4537 SetOperandAt(0, obj);
4479 SetOperandAt(1, key); 4538 SetOperandAt(1, key);
4480 SetOperandAt(2, context); 4539 SetOperandAt(2, context);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
4591 private: 4650 private:
4592 Handle<String> name_; 4651 Handle<String> name_;
4593 StrictModeFlag strict_mode_flag_; 4652 StrictModeFlag strict_mode_flag_;
4594 }; 4653 };
4595 4654
4596 4655
4597 class HStoreKeyed 4656 class HStoreKeyed
4598 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 4657 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4599 public: 4658 public:
4600 HStoreKeyed(HValue* obj, HValue* key, HValue* val, 4659 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
4601 ElementsKind elements_kind) 4660 ElementsKind elements_kind,
4661 bool defer_initialization = false)
danno 2012/11/28 14:42:10 can you not have to care whether this is deferred,
mvstanton 2012/12/04 11:39:58 That didn't work because there are protections aro
4602 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { 4662 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
4603 SetOperandAt(0, obj); 4663 SetOperandAt(0, obj);
4604 SetOperandAt(1, key); 4664 SetOperandAt(1, key);
4605 SetOperandAt(2, val); 4665 SetOperandAt(2, val);
4606 4666
4667 #ifdef DEBUG
4668 initialized_ = !defer_initialization;
4669
4670 // Deferred initialization should only be invoked for fast elements
4671 // that are not external.
4672 ASSERT(!(defer_initialization && is_external()));
4673 #endif
4674
4607 if (is_external()) { 4675 if (is_external()) {
4608 SetGVNFlag(kChangesSpecializedArrayElements); 4676 SetGVNFlag(kChangesSpecializedArrayElements);
4677 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
4678 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
4679 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
4680 SetFlag(kTruncatingToInt32);
4681 }
4682 } else if (defer_initialization) {
4683 // We don't know what we'll have later.
4684 // Initialize for the worst case
4685 SetGVNFlag(kChangesDoubleArrayElements);
4686 SetFlag(kDeoptimizeOnUndefined);
4687 SetGVNFlag(kChangesArrayElements);
4609 } else if (IsFastDoubleElementsKind(elements_kind)) { 4688 } else if (IsFastDoubleElementsKind(elements_kind)) {
4610 SetGVNFlag(kChangesDoubleArrayElements); 4689 SetGVNFlag(kChangesDoubleArrayElements);
4611 SetFlag(kDeoptimizeOnUndefined); 4690 SetFlag(kDeoptimizeOnUndefined);
4612 } else { 4691 } else {
4613 SetGVNFlag(kChangesArrayElements); 4692 SetGVNFlag(kChangesArrayElements);
4614 } 4693 }
4694 }
4615 4695
4616 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 4696 #ifdef DEBUG
4617 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && 4697 bool Initialized() const { return initialized_; }
4618 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { 4698 #endif
4619 SetFlag(kTruncatingToInt32); 4699
4700 void PerformDeferredInitialization(ElementsKind new_elements_kind) {
4701 #ifdef DEBUG
4702 ASSERT(!initialized_);
4703 initialized_ = true;
4704 #endif
4705 if (new_elements_kind != elements_kind_) {
4706 elements_kind_ = new_elements_kind;
4707 }
4708
4709 // Adjust flags appropriately
4710 if (IsFastDoubleElementsKind(elements_kind())) {
4711 ClearGVNFlag(kChangesArrayElements);
4712 } else {
4713 ClearGVNFlag(kChangesDoubleArrayElements);
4714 ClearFlag(kDeoptimizeOnUndefined);
4620 } 4715 }
4621 } 4716 }
4622 4717
4623 virtual Representation RequiredInputRepresentation(int index) { 4718 virtual Representation RequiredInputRepresentation(int index) {
4719 ASSERT(initialized_);
4624 // kind_fast: tagged[int32] = tagged 4720 // kind_fast: tagged[int32] = tagged
4625 // kind_double: tagged[int32] = double 4721 // kind_double: tagged[int32] = double
4626 // kind_external: external[int32] = (double | int32) 4722 // kind_external: external[int32] = (double | int32)
4627 if (index == 0) { 4723 if (index == 0) {
4628 return is_external() ? Representation::External() 4724 return is_external() ? Representation::External()
4629 : Representation::Tagged(); 4725 : Representation::Tagged();
4630 } else if (index == 1) { 4726 } else if (index == 1) {
4631 return Representation::Integer32(); 4727 return Representation::Integer32();
4632 } 4728 }
4633 4729
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4672 4768
4673 bool NeedsWriteBarrier() { 4769 bool NeedsWriteBarrier() {
4674 if (value_is_smi()) { 4770 if (value_is_smi()) {
4675 return false; 4771 return false;
4676 } else { 4772 } else {
4677 return StoringValueNeedsWriteBarrier(value()); 4773 return StoringValueNeedsWriteBarrier(value());
4678 } 4774 }
4679 } 4775 }
4680 4776
4681 bool NeedsCanonicalization(); 4777 bool NeedsCanonicalization();
4682
4683 virtual void PrintDataTo(StringStream* stream); 4778 virtual void PrintDataTo(StringStream* stream);
4684 4779
4685 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) 4780 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
4686 4781
4687 private: 4782 private:
4688 ElementsKind elements_kind_; 4783 ElementsKind elements_kind_;
4689 uint32_t index_offset_; 4784 uint32_t index_offset_;
4690 bool is_dehoisted_; 4785 bool is_dehoisted_;
4786 #ifdef DEBUG
4787 bool initialized_;
4788 #endif
4691 }; 4789 };
4692 4790
4693 4791
4694 class HStoreKeyedGeneric: public HTemplateInstruction<4> { 4792 class HStoreKeyedGeneric: public HTemplateInstruction<4> {
4695 public: 4793 public:
4696 HStoreKeyedGeneric(HValue* context, 4794 HStoreKeyedGeneric(HValue* context,
4697 HValue* object, 4795 HValue* object,
4698 HValue* key, 4796 HValue* key,
4699 HValue* value, 4797 HValue* value,
4700 StrictModeFlag strict_mode_flag) 4798 StrictModeFlag strict_mode_flag)
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
5386 virtual bool IsDeletable() const { return true; } 5484 virtual bool IsDeletable() const { return true; }
5387 }; 5485 };
5388 5486
5389 5487
5390 #undef DECLARE_INSTRUCTION 5488 #undef DECLARE_INSTRUCTION
5391 #undef DECLARE_CONCRETE_INSTRUCTION 5489 #undef DECLARE_CONCRETE_INSTRUCTION
5392 5490
5393 } } // namespace v8::internal 5491 } } // namespace v8::internal
5394 5492
5395 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5493 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« src/hydrogen.cc ('K') | « src/hydrogen.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698