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 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 : SequentialStringKey<uint8_t>(str, seed) { } | 492 : SequentialStringKey<uint8_t>(str, seed) { } |
493 | 493 |
494 virtual bool IsMatch(Object* string) { | 494 virtual bool IsMatch(Object* string) { |
495 return String::cast(string)->IsOneByteEqualTo(string_); | 495 return String::cast(string)->IsOneByteEqualTo(string_); |
496 } | 496 } |
497 | 497 |
498 virtual MaybeObject* AsObject(Heap* heap); | 498 virtual MaybeObject* AsObject(Heap* heap); |
499 }; | 499 }; |
500 | 500 |
501 | 501 |
502 class SubStringOneByteStringKey : public HashTableKey { | 502 template<class Char> |
| 503 class SubStringKey : public HashTableKey { |
503 public: | 504 public: |
504 explicit SubStringOneByteStringKey(Handle<SeqOneByteString> string, | 505 SubStringKey(Handle<String> string, int from, int length) |
505 int from, | 506 : string_(string), from_(from), length_(length) { |
506 int length) | 507 if (string_->IsSlicedString()) { |
507 : string_(string), from_(from), length_(length) { } | 508 string_ = Handle<String>(Unslice(*string_, &from_)); |
| 509 } |
| 510 ASSERT(string_->IsSeqString() || string->IsExternalString()); |
| 511 } |
508 | 512 |
509 virtual uint32_t Hash() { | 513 virtual uint32_t Hash() { |
510 ASSERT(length_ >= 0); | 514 ASSERT(length_ >= 0); |
511 ASSERT(from_ + length_ <= string_->length()); | 515 ASSERT(from_ + length_ <= string_->length()); |
512 uint8_t* chars = string_->GetChars() + from_; | 516 const Char* chars = GetChars() + from_; |
513 hash_field_ = StringHasher::HashSequentialString( | 517 hash_field_ = StringHasher::HashSequentialString( |
514 chars, length_, string_->GetHeap()->HashSeed()); | 518 chars, length_, string_->GetHeap()->HashSeed()); |
515 uint32_t result = hash_field_ >> String::kHashShift; | 519 uint32_t result = hash_field_ >> String::kHashShift; |
516 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 520 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
517 return result; | 521 return result; |
518 } | 522 } |
519 | 523 |
520 | |
521 virtual uint32_t HashForObject(Object* other) { | 524 virtual uint32_t HashForObject(Object* other) { |
522 return String::cast(other)->Hash(); | 525 return String::cast(other)->Hash(); |
523 } | 526 } |
524 | 527 |
525 virtual bool IsMatch(Object* string) { | 528 virtual bool IsMatch(Object* string); |
526 Vector<const uint8_t> chars(string_->GetChars() + from_, length_); | |
527 return String::cast(string)->IsOneByteEqualTo(chars); | |
528 } | |
529 | |
530 virtual MaybeObject* AsObject(Heap* heap); | 529 virtual MaybeObject* AsObject(Heap* heap); |
531 | 530 |
532 private: | 531 private: |
533 Handle<SeqOneByteString> string_; | 532 const Char* GetChars(); |
| 533 String* Unslice(String* string, int* offset) { |
| 534 while (string->IsSlicedString()) { |
| 535 SlicedString* sliced = SlicedString::cast(string); |
| 536 *offset += sliced->offset(); |
| 537 string = sliced->parent(); |
| 538 } |
| 539 return string; |
| 540 } |
| 541 |
| 542 Handle<String> string_; |
534 int from_; | 543 int from_; |
535 int length_; | 544 int length_; |
536 uint32_t hash_field_; | 545 uint32_t hash_field_; |
537 }; | 546 }; |
538 | 547 |
539 | 548 |
540 class TwoByteStringKey : public SequentialStringKey<uc16> { | 549 class TwoByteStringKey : public SequentialStringKey<uc16> { |
541 public: | 550 public: |
542 explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed) | 551 explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed) |
543 : SequentialStringKey<uc16>(str, seed) { } | 552 : SequentialStringKey<uc16>(str, seed) { } |
(...skipping 3115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3659 | 3668 |
3660 | 3669 |
3661 template <class Traits> | 3670 template <class Traits> |
3662 typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) { | 3671 typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) { |
3663 ASSERT((index >= 0) && (index < this->length())); | 3672 ASSERT((index >= 0) && (index < this->length())); |
3664 ElementType* ptr = reinterpret_cast<ElementType*>( | 3673 ElementType* ptr = reinterpret_cast<ElementType*>( |
3665 FIELD_ADDR(this, kDataOffset)); | 3674 FIELD_ADDR(this, kDataOffset)); |
3666 return ptr[index]; | 3675 return ptr[index]; |
3667 } | 3676 } |
3668 | 3677 |
| 3678 |
| 3679 template<> inline |
| 3680 FixedTypedArray<Float64ArrayTraits>::ElementType |
| 3681 FixedTypedArray<Float64ArrayTraits>::get_scalar(int index) { |
| 3682 ASSERT((index >= 0) && (index < this->length())); |
| 3683 return READ_DOUBLE_FIELD(this, ElementOffset(index)); |
| 3684 } |
| 3685 |
| 3686 |
3669 template <class Traits> | 3687 template <class Traits> |
3670 void FixedTypedArray<Traits>::set(int index, ElementType value) { | 3688 void FixedTypedArray<Traits>::set(int index, ElementType value) { |
3671 ASSERT((index >= 0) && (index < this->length())); | 3689 ASSERT((index >= 0) && (index < this->length())); |
3672 ElementType* ptr = reinterpret_cast<ElementType*>( | 3690 ElementType* ptr = reinterpret_cast<ElementType*>( |
3673 FIELD_ADDR(this, kDataOffset)); | 3691 FIELD_ADDR(this, kDataOffset)); |
3674 ptr[index] = value; | 3692 ptr[index] = value; |
3675 } | 3693 } |
3676 | 3694 |
3677 | 3695 |
| 3696 template<> inline |
| 3697 void FixedTypedArray<Float64ArrayTraits>::set( |
| 3698 int index, Float64ArrayTraits::ElementType value) { |
| 3699 ASSERT((index >= 0) && (index < this->length())); |
| 3700 WRITE_DOUBLE_FIELD(this, ElementOffset(index), value); |
| 3701 } |
| 3702 |
| 3703 |
3678 template <class Traits> | 3704 template <class Traits> |
3679 MaybeObject* FixedTypedArray<Traits>::get(int index) { | 3705 MaybeObject* FixedTypedArray<Traits>::get(int index) { |
3680 return Traits::ToObject(GetHeap(), get_scalar(index)); | 3706 return Traits::ToObject(GetHeap(), get_scalar(index)); |
3681 } | 3707 } |
3682 | 3708 |
3683 template <class Traits> | 3709 template <class Traits> |
3684 MaybeObject* FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) { | 3710 MaybeObject* FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) { |
3685 ElementType cast_value = Traits::defaultValue(); | 3711 ElementType cast_value = Traits::defaultValue(); |
3686 if (index < static_cast<uint32_t>(length())) { | 3712 if (index < static_cast<uint32_t>(length())) { |
3687 if (value->IsSmi()) { | 3713 if (value->IsSmi()) { |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3955 set_bit_field3(IsShared::update(bit_field3(), value)); | 3981 set_bit_field3(IsShared::update(bit_field3(), value)); |
3956 } | 3982 } |
3957 | 3983 |
3958 | 3984 |
3959 bool Map::is_shared() { | 3985 bool Map::is_shared() { |
3960 return IsShared::decode(bit_field3()); | 3986 return IsShared::decode(bit_field3()); |
3961 } | 3987 } |
3962 | 3988 |
3963 | 3989 |
3964 void Map::set_dictionary_map(bool value) { | 3990 void Map::set_dictionary_map(bool value) { |
3965 if (value) mark_unstable(); | 3991 uint32_t new_bit_field3 = DictionaryMap::update(bit_field3(), value); |
3966 set_bit_field3(DictionaryMap::update(bit_field3(), value)); | 3992 new_bit_field3 = IsUnstable::update(new_bit_field3, value); |
| 3993 set_bit_field3(new_bit_field3); |
3967 } | 3994 } |
3968 | 3995 |
3969 | 3996 |
3970 bool Map::is_dictionary_map() { | 3997 bool Map::is_dictionary_map() { |
3971 return DictionaryMap::decode(bit_field3()); | 3998 return DictionaryMap::decode(bit_field3()); |
3972 } | 3999 } |
3973 | 4000 |
3974 | 4001 |
3975 Code::Flags Code::flags() { | 4002 Code::Flags Code::flags() { |
3976 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); | 4003 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4140 for (int g = kGroupCount - 1; g > group; g--) { | 4167 for (int g = kGroupCount - 1; g > group; g--) { |
4141 if (starts.at(g) < starts.at(g + 1)) { | 4168 if (starts.at(g) < starts.at(g + 1)) { |
4142 copy(starts.at(g), starts.at(g + 1)); | 4169 copy(starts.at(g), starts.at(g + 1)); |
4143 } | 4170 } |
4144 } | 4171 } |
4145 } | 4172 } |
4146 | 4173 |
4147 | 4174 |
4148 void Code::set_flags(Code::Flags flags) { | 4175 void Code::set_flags(Code::Flags flags) { |
4149 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); | 4176 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); |
4150 // Make sure that all call stubs have an arguments count. | |
4151 ASSERT((ExtractKindFromFlags(flags) != CALL_IC && | |
4152 ExtractKindFromFlags(flags) != KEYED_CALL_IC) || | |
4153 ExtractArgumentsCountFromFlags(flags) >= 0); | |
4154 WRITE_INT_FIELD(this, kFlagsOffset, flags); | 4177 WRITE_INT_FIELD(this, kFlagsOffset, flags); |
4155 } | 4178 } |
4156 | 4179 |
4157 | 4180 |
4158 Code::Kind Code::kind() { | 4181 Code::Kind Code::kind() { |
4159 return ExtractKindFromFlags(flags()); | 4182 return ExtractKindFromFlags(flags()); |
4160 } | 4183 } |
4161 | 4184 |
4162 | 4185 |
4163 InlineCacheState Code::ic_state() { | 4186 InlineCacheState Code::ic_state() { |
(...skipping 21 matching lines...) Expand all Loading... |
4185 return ExtractExtendedExtraICStateFromFlags(flags()); | 4208 return ExtractExtendedExtraICStateFromFlags(flags()); |
4186 } | 4209 } |
4187 | 4210 |
4188 | 4211 |
4189 Code::StubType Code::type() { | 4212 Code::StubType Code::type() { |
4190 return ExtractTypeFromFlags(flags()); | 4213 return ExtractTypeFromFlags(flags()); |
4191 } | 4214 } |
4192 | 4215 |
4193 | 4216 |
4194 int Code::arguments_count() { | 4217 int Code::arguments_count() { |
4195 ASSERT(is_call_stub() || is_keyed_call_stub() || | 4218 ASSERT(kind() == STUB || is_handler()); |
4196 kind() == STUB || is_handler()); | |
4197 return ExtractArgumentsCountFromFlags(flags()); | 4219 return ExtractArgumentsCountFromFlags(flags()); |
4198 } | 4220 } |
4199 | 4221 |
4200 | 4222 |
4201 // For initialization. | 4223 // For initialization. |
4202 void Code::set_raw_kind_specific_flags1(int value) { | 4224 void Code::set_raw_kind_specific_flags1(int value) { |
4203 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value); | 4225 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value); |
4204 } | 4226 } |
4205 | 4227 |
4206 | 4228 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4241 bool Code::has_major_key() { | 4263 bool Code::has_major_key() { |
4242 return kind() == STUB || | 4264 return kind() == STUB || |
4243 kind() == HANDLER || | 4265 kind() == HANDLER || |
4244 kind() == BINARY_OP_IC || | 4266 kind() == BINARY_OP_IC || |
4245 kind() == COMPARE_IC || | 4267 kind() == COMPARE_IC || |
4246 kind() == COMPARE_NIL_IC || | 4268 kind() == COMPARE_NIL_IC || |
4247 kind() == LOAD_IC || | 4269 kind() == LOAD_IC || |
4248 kind() == KEYED_LOAD_IC || | 4270 kind() == KEYED_LOAD_IC || |
4249 kind() == STORE_IC || | 4271 kind() == STORE_IC || |
4250 kind() == KEYED_STORE_IC || | 4272 kind() == KEYED_STORE_IC || |
4251 kind() == KEYED_CALL_IC || | |
4252 kind() == TO_BOOLEAN_IC; | 4273 kind() == TO_BOOLEAN_IC; |
4253 } | 4274 } |
4254 | 4275 |
4255 | 4276 |
4256 bool Code::optimizable() { | 4277 bool Code::optimizable() { |
4257 ASSERT_EQ(FUNCTION, kind()); | 4278 ASSERT_EQ(FUNCTION, kind()); |
4258 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1; | 4279 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1; |
4259 } | 4280 } |
4260 | 4281 |
4261 | 4282 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4394 | 4415 |
4395 void Code::set_back_edges_patched_for_osr(bool value) { | 4416 void Code::set_back_edges_patched_for_osr(bool value) { |
4396 ASSERT_EQ(FUNCTION, kind()); | 4417 ASSERT_EQ(FUNCTION, kind()); |
4397 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset); | 4418 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset); |
4398 int updated = BackEdgesPatchedForOSRField::update(previous, value); | 4419 int updated = BackEdgesPatchedForOSRField::update(previous, value); |
4399 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated); | 4420 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated); |
4400 } | 4421 } |
4401 | 4422 |
4402 | 4423 |
4403 | 4424 |
4404 CheckType Code::check_type() { | |
4405 ASSERT(is_call_stub() || is_keyed_call_stub()); | |
4406 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset); | |
4407 return static_cast<CheckType>(type); | |
4408 } | |
4409 | |
4410 | |
4411 void Code::set_check_type(CheckType value) { | |
4412 ASSERT(is_call_stub() || is_keyed_call_stub()); | |
4413 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value); | |
4414 } | |
4415 | |
4416 | |
4417 byte Code::to_boolean_state() { | 4425 byte Code::to_boolean_state() { |
4418 return extended_extra_ic_state(); | 4426 return extended_extra_ic_state(); |
4419 } | 4427 } |
4420 | 4428 |
4421 | 4429 |
4422 bool Code::has_function_cache() { | 4430 bool Code::has_function_cache() { |
4423 ASSERT(kind() == STUB); | 4431 ASSERT(kind() == STUB); |
4424 return HasFunctionCacheField::decode( | 4432 return HasFunctionCacheField::decode( |
4425 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset)); | 4433 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset)); |
4426 } | 4434 } |
(...skipping 27 matching lines...) Expand all Loading... |
4454 switch (kind) { | 4462 switch (kind) { |
4455 #define CASE(name) case name: return true; | 4463 #define CASE(name) case name: return true; |
4456 IC_KIND_LIST(CASE) | 4464 IC_KIND_LIST(CASE) |
4457 #undef CASE | 4465 #undef CASE |
4458 default: return false; | 4466 default: return false; |
4459 } | 4467 } |
4460 } | 4468 } |
4461 | 4469 |
4462 | 4470 |
4463 bool Code::is_keyed_stub() { | 4471 bool Code::is_keyed_stub() { |
4464 return is_keyed_load_stub() || is_keyed_store_stub() || is_keyed_call_stub(); | 4472 return is_keyed_load_stub() || is_keyed_store_stub(); |
4465 } | 4473 } |
4466 | 4474 |
4467 | 4475 |
4468 bool Code::is_debug_stub() { | 4476 bool Code::is_debug_stub() { |
4469 return ic_state() == DEBUG_STUB; | 4477 return ic_state() == DEBUG_STUB; |
4470 } | 4478 } |
4471 | 4479 |
4472 | 4480 |
4473 ConstantPoolArray* Code::constant_pool() { | 4481 ConstantPoolArray* Code::constant_pool() { |
4474 return ConstantPoolArray::cast(READ_FIELD(this, kConstantPoolOffset)); | 4482 return ConstantPoolArray::cast(READ_FIELD(this, kConstantPoolOffset)); |
4475 } | 4483 } |
4476 | 4484 |
4477 | 4485 |
4478 void Code::set_constant_pool(Object* value) { | 4486 void Code::set_constant_pool(Object* value) { |
4479 ASSERT(value->IsConstantPoolArray()); | 4487 ASSERT(value->IsConstantPoolArray()); |
4480 WRITE_FIELD(this, kConstantPoolOffset, value); | 4488 WRITE_FIELD(this, kConstantPoolOffset, value); |
4481 WRITE_BARRIER(GetHeap(), this, kConstantPoolOffset, value); | 4489 WRITE_BARRIER(GetHeap(), this, kConstantPoolOffset, value); |
4482 } | 4490 } |
4483 | 4491 |
4484 | 4492 |
4485 Code::Flags Code::ComputeFlags(Kind kind, | 4493 Code::Flags Code::ComputeFlags(Kind kind, |
4486 InlineCacheState ic_state, | 4494 InlineCacheState ic_state, |
4487 ExtraICState extra_ic_state, | 4495 ExtraICState extra_ic_state, |
4488 StubType type, | 4496 StubType type, |
4489 int argc, | 4497 int argc, |
4490 InlineCacheHolderFlag holder) { | 4498 InlineCacheHolderFlag holder) { |
4491 ASSERT(argc <= Code::kMaxArguments); | 4499 ASSERT(argc <= Code::kMaxArguments); |
4492 // Since the extended extra ic state overlaps with the argument count | |
4493 // for CALL_ICs, do so checks to make sure that they don't interfere. | |
4494 ASSERT((kind != Code::CALL_IC && | |
4495 kind != Code::KEYED_CALL_IC) || | |
4496 (ExtraICStateField::encode(extra_ic_state) | true)); | |
4497 // Compute the bit mask. | 4500 // Compute the bit mask. |
4498 unsigned int bits = KindField::encode(kind) | 4501 unsigned int bits = KindField::encode(kind) |
4499 | ICStateField::encode(ic_state) | 4502 | ICStateField::encode(ic_state) |
4500 | TypeField::encode(type) | 4503 | TypeField::encode(type) |
4501 | ExtendedExtraICStateField::encode(extra_ic_state) | 4504 | ExtendedExtraICStateField::encode(extra_ic_state) |
4502 | CacheHolderField::encode(holder); | 4505 | CacheHolderField::encode(holder); |
4503 if (!Code::needs_extended_extra_ic_state(kind)) { | 4506 if (!Code::needs_extended_extra_ic_state(kind)) { |
4504 bits |= (argc << kArgumentsCountShift); | 4507 bits |= (argc << kArgumentsCountShift); |
4505 } | 4508 } |
4506 return static_cast<Flags>(bits); | 4509 return static_cast<Flags>(bits); |
(...skipping 2271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6778 #undef READ_UINT32_FIELD | 6781 #undef READ_UINT32_FIELD |
6779 #undef WRITE_UINT32_FIELD | 6782 #undef WRITE_UINT32_FIELD |
6780 #undef READ_SHORT_FIELD | 6783 #undef READ_SHORT_FIELD |
6781 #undef WRITE_SHORT_FIELD | 6784 #undef WRITE_SHORT_FIELD |
6782 #undef READ_BYTE_FIELD | 6785 #undef READ_BYTE_FIELD |
6783 #undef WRITE_BYTE_FIELD | 6786 #undef WRITE_BYTE_FIELD |
6784 | 6787 |
6785 } } // namespace v8::internal | 6788 } } // namespace v8::internal |
6786 | 6789 |
6787 #endif // V8_OBJECTS_INL_H_ | 6790 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |