diff options
Diffstat (limited to 'deps/v8/src/objects-inl.h')
-rw-r--r-- | deps/v8/src/objects-inl.h | 270 |
1 files changed, 170 insertions, 100 deletions
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 67d64c4779..cc264f6aef 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -509,7 +509,7 @@ class SequentialStringKey : public HashTableKey { explicit SequentialStringKey(Vector<const Char> string, uint32_t seed) : string_(string), hash_field_(0), seed_(seed) { } - uint32_t Hash() OVERRIDE { + uint32_t Hash() override { hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(), string_.length(), seed_); @@ -520,7 +520,7 @@ class SequentialStringKey : public HashTableKey { } - uint32_t HashForObject(Object* other) OVERRIDE { + uint32_t HashForObject(Object* other) override { return String::cast(other)->Hash(); } @@ -535,11 +535,11 @@ class OneByteStringKey : public SequentialStringKey<uint8_t> { OneByteStringKey(Vector<const uint8_t> str, uint32_t seed) : SequentialStringKey<uint8_t>(str, seed) { } - bool IsMatch(Object* string) OVERRIDE { + bool IsMatch(Object* string) override { return String::cast(string)->IsOneByteEqualTo(string_); } - Handle<Object> AsHandle(Isolate* isolate) OVERRIDE; + Handle<Object> AsHandle(Isolate* isolate) override; }; @@ -550,7 +550,7 @@ class SeqOneByteSubStringKey : public HashTableKey { DCHECK(string_->IsSeqOneByteString()); } - uint32_t Hash() OVERRIDE { + uint32_t Hash() override { DCHECK(length_ >= 0); DCHECK(from_ + length_ <= string_->length()); const uint8_t* chars = string_->GetChars() + from_; @@ -561,12 +561,12 @@ class SeqOneByteSubStringKey : public HashTableKey { return result; } - uint32_t HashForObject(Object* other) OVERRIDE { + uint32_t HashForObject(Object* other) override { return String::cast(other)->Hash(); } - bool IsMatch(Object* string) OVERRIDE; - Handle<Object> AsHandle(Isolate* isolate) OVERRIDE; + bool IsMatch(Object* string) override; + Handle<Object> AsHandle(Isolate* isolate) override; private: Handle<SeqOneByteString> string_; @@ -581,11 +581,11 @@ class TwoByteStringKey : public SequentialStringKey<uc16> { explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed) : SequentialStringKey<uc16>(str, seed) { } - bool IsMatch(Object* string) OVERRIDE { + bool IsMatch(Object* string) override { return String::cast(string)->IsTwoByteEqualTo(string_); } - Handle<Object> AsHandle(Isolate* isolate) OVERRIDE; + Handle<Object> AsHandle(Isolate* isolate) override; }; @@ -595,11 +595,11 @@ class Utf8StringKey : public HashTableKey { explicit Utf8StringKey(Vector<const char> string, uint32_t seed) : string_(string), hash_field_(0), seed_(seed) { } - bool IsMatch(Object* string) OVERRIDE { + bool IsMatch(Object* string) override { return String::cast(string)->IsUtf8EqualTo(string_); } - uint32_t Hash() OVERRIDE { + uint32_t Hash() override { if (hash_field_ != 0) return hash_field_ >> String::kHashShift; hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_); uint32_t result = hash_field_ >> String::kHashShift; @@ -607,11 +607,11 @@ class Utf8StringKey : public HashTableKey { return result; } - uint32_t HashForObject(Object* other) OVERRIDE { + uint32_t HashForObject(Object* other) override { return String::cast(other)->Hash(); } - Handle<Object> AsHandle(Isolate* isolate) OVERRIDE { + Handle<Object> AsHandle(Isolate* isolate) override { if (hash_field_ == 0) Hash(); return isolate->factory()->NewInternalizedStringFromUtf8( string_, chars_, hash_field_); @@ -1849,6 +1849,12 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object, } +bool JSObject::WouldConvertToSlowElements(Handle<Object> key) { + uint32_t index; + return key->ToArrayIndex(&index) && WouldConvertToSlowElements(index); +} + + void JSObject::SetMapAndElements(Handle<JSObject> object, Handle<Map> new_map, Handle<FixedArrayBase> value) { @@ -1896,17 +1902,7 @@ void Oddball::set_kind(byte value) { } -Object* Cell::value() const { - return READ_FIELD(this, kValueOffset); -} - - -void Cell::set_value(Object* val, WriteBarrierMode ignored) { - // The write barrier is not used for global property cells. - DCHECK(!val->IsPropertyCell() && !val->IsCell()); - WRITE_FIELD(this, kValueOffset, val); -} - +ACCESSORS(Cell, value, Object, kValueOffset) ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset) ACCESSORS(PropertyCell, value, Object, kValueOffset) @@ -1921,7 +1917,13 @@ void WeakCell::clear() { void WeakCell::initialize(HeapObject* val) { WRITE_FIELD(this, kValueOffset, val); - WRITE_BARRIER(GetHeap(), this, kValueOffset, val); + Heap* heap = GetHeap(); + // We just have to execute the generational barrier here because we never + // mark through a weak cell and collect evacuation candidates when we process + // all weak cells. + if (heap->InNewSpace(val)) { + heap->RecordWrite(address(), kValueOffset); + } } @@ -1989,9 +1991,7 @@ int JSObject::GetHeaderSize() { case JS_MESSAGE_OBJECT_TYPE: return JSMessageObject::kSize; default: - // TODO(jkummerow): Re-enable this. Blink currently hits this - // from its CustomElementConstructorBuilder. - // UNREACHABLE(); + UNREACHABLE(); return 0; } } @@ -2368,7 +2368,7 @@ bool WeakFixedArray::IsEmptySlot(int index) const { } -void WeakFixedArray::clear(int index) { +void WeakFixedArray::Clear(int index) { FixedArray::cast(this)->set(index + kFirstIndex, Smi::FromInt(0)); } @@ -3257,18 +3257,21 @@ DescriptorArray::WhitenessWitness::~WhitenessWitness() { } -template<typename Derived, typename Shape, typename Key> -int HashTable<Derived, Shape, Key>::ComputeCapacity(int at_least_space_for) { - const int kMinCapacity = 32; +int HashTableBase::ComputeCapacity(int at_least_space_for) { + const int kMinCapacity = 4; int capacity = base::bits::RoundUpToPowerOfTwo32(at_least_space_for * 2); - if (capacity < kMinCapacity) { - capacity = kMinCapacity; // Guarantee min capacity. - } - return capacity; + return Max(capacity, kMinCapacity); } -template<typename Derived, typename Shape, typename Key> +int HashTableBase::ComputeCapacityForSerialization(int at_least_space_for) { + const int kMinCapacity = 1; + int capacity = base::bits::RoundUpToPowerOfTwo32(at_least_space_for); + return Max(capacity, kMinCapacity); +} + + +template <typename Derived, typename Shape, typename Key> int HashTable<Derived, Shape, Key>::FindEntry(Key key) { return FindEntry(GetIsolate(), key); } @@ -4308,14 +4311,6 @@ typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) { } -template<> inline -FixedTypedArray<Float64ArrayTraits>::ElementType - FixedTypedArray<Float64ArrayTraits>::get_scalar(int index) { - DCHECK((index >= 0) && (index < this->length())); - return READ_DOUBLE_FIELD(this, ElementOffset(index)); -} - - template <class Traits> void FixedTypedArray<Traits>::set(int index, ElementType value) { DCHECK((index >= 0) && (index < this->length())); @@ -4325,14 +4320,6 @@ void FixedTypedArray<Traits>::set(int index, ElementType value) { } -template<> inline -void FixedTypedArray<Float64ArrayTraits>::set( - int index, Float64ArrayTraits::ElementType value) { - DCHECK((index >= 0) && (index < this->length())); - WRITE_DOUBLE_FIELD(this, ElementOffset(index), value); -} - - template <class Traits> typename Traits::ElementType FixedTypedArray<Traits>::from_int(int value) { return static_cast<ElementType>(value); @@ -4385,23 +4372,25 @@ Handle<Object> FixedTypedArray<Traits>::get( template <class Traits> Handle<Object> FixedTypedArray<Traits>::SetValue( - Handle<FixedTypedArray<Traits> > array, - uint32_t index, - Handle<Object> value) { + Handle<JSObject> holder, Handle<FixedTypedArray<Traits> > array, + uint32_t index, Handle<Object> value) { ElementType cast_value = Traits::defaultValue(); - if (index < static_cast<uint32_t>(array->length())) { - if (value->IsSmi()) { - int int_value = Handle<Smi>::cast(value)->value(); - cast_value = from_int(int_value); - } else if (value->IsHeapNumber()) { - double double_value = Handle<HeapNumber>::cast(value)->value(); - cast_value = from_double(double_value); - } else { - // Clamp undefined to the default value. All other types have been - // converted to a number type further up in the call chain. - DCHECK(value->IsUndefined()); + Handle<JSArrayBufferView> view = Handle<JSArrayBufferView>::cast(holder); + if (!view->WasNeutered()) { + if (index < static_cast<uint32_t>(array->length())) { + if (value->IsSmi()) { + int int_value = Handle<Smi>::cast(value)->value(); + cast_value = from_int(int_value); + } else if (value->IsHeapNumber()) { + double double_value = Handle<HeapNumber>::cast(value)->value(); + cast_value = from_double(double_value); + } else { + // Clamp undefined to the default value. All other types have been + // converted to a number type further up in the call chain. + DCHECK(value->IsUndefined()); + } + array->set(index, cast_value); } - array->set(index, cast_value); } return Traits::ToHandle(array->GetIsolate(), cast_value); } @@ -4584,9 +4573,7 @@ void Map::set_unused_property_fields(int value) { } -byte Map::bit_field() { - return READ_BYTE_FIELD(this, kBitFieldOffset); -} +byte Map::bit_field() const { return READ_BYTE_FIELD(this, kBitFieldOffset); } void Map::set_bit_field(byte value) { @@ -4594,9 +4581,7 @@ void Map::set_bit_field(byte value) { } -byte Map::bit_field2() { - return READ_BYTE_FIELD(this, kBitField2Offset); -} +byte Map::bit_field2() const { return READ_BYTE_FIELD(this, kBitField2Offset); } void Map::set_bit_field2(byte value) { @@ -4659,7 +4644,7 @@ void Map::set_is_prototype_map(bool value) { set_bit_field2(IsPrototypeMapBits::update(bit_field2(), value)); } -bool Map::is_prototype_map() { +bool Map::is_prototype_map() const { return IsPrototypeMapBits::decode(bit_field2()); } @@ -5353,7 +5338,7 @@ void Map::set_bit_field3(uint32_t bits) { } -uint32_t Map::bit_field3() { +uint32_t Map::bit_field3() const { return READ_UINT32_FIELD(this, kBitField3Offset); } @@ -5395,7 +5380,21 @@ Map* Map::ElementsTransitionMap() { } -ACCESSORS(Map, raw_transitions, Object, kTransitionsOffset) +ACCESSORS(Map, raw_transitions, Object, kTransitionsOrPrototypeInfoOffset) + + +Object* Map::prototype_info() const { + DCHECK(is_prototype_map()); + return READ_FIELD(this, Map::kTransitionsOrPrototypeInfoOffset); +} + + +void Map::set_prototype_info(Object* value, WriteBarrierMode mode) { + DCHECK(is_prototype_map()); + WRITE_FIELD(this, Map::kTransitionsOrPrototypeInfoOffset, value); + CONDITIONAL_WRITE_BARRIER( + GetHeap(), this, Map::kTransitionsOrPrototypeInfoOffset, value, mode); +} void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { @@ -5455,6 +5454,10 @@ ACCESSORS(ExecutableAccessorInfo, data, Object, kDataOffset) ACCESSORS(Box, value, Object, kValueOffset) +ACCESSORS(PrototypeInfo, prototype_users, Object, kPrototypeUsersOffset) +ACCESSORS(PrototypeInfo, validity_cell, Object, kValidityCellOffset) +ACCESSORS(PrototypeInfo, constructor_name, Object, kConstructorNameOffset) + ACCESSORS(AccessorPair, getter, Object, kGetterOffset) ACCESSORS(AccessorPair, setter, Object, kSetterOffset) @@ -6417,48 +6420,103 @@ void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) { ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset) -ACCESSORS_TO_SMI(JSArrayBuffer, flag, kFlagOffset) -bool JSArrayBuffer::is_external() { - return BooleanBit::get(flag(), kIsExternalBit); +void JSArrayBuffer::set_bit_field(uint32_t bits) { + if (kInt32Size != kPointerSize) { +#if V8_TARGET_LITTLE_ENDIAN + WRITE_UINT32_FIELD(this, kBitFieldSlot + kInt32Size, 0); +#else + WRITE_UINT32_FIELD(this, kBitFieldSlot, 0); +#endif + } + WRITE_UINT32_FIELD(this, kBitFieldOffset, bits); } -void JSArrayBuffer::set_is_external(bool value) { - set_flag(BooleanBit::set(flag(), kIsExternalBit, value)); +uint32_t JSArrayBuffer::bit_field() const { + return READ_UINT32_FIELD(this, kBitFieldOffset); } -bool JSArrayBuffer::should_be_freed() { - return BooleanBit::get(flag(), kShouldBeFreed); -} +bool JSArrayBuffer::is_external() { return IsExternal::decode(bit_field()); } -void JSArrayBuffer::set_should_be_freed(bool value) { - set_flag(BooleanBit::set(flag(), kShouldBeFreed, value)); +void JSArrayBuffer::set_is_external(bool value) { + set_bit_field(IsExternal::update(bit_field(), value)); } bool JSArrayBuffer::is_neuterable() { - return BooleanBit::get(flag(), kIsNeuterableBit); + return IsNeuterable::decode(bit_field()); } void JSArrayBuffer::set_is_neuterable(bool value) { - set_flag(BooleanBit::set(flag(), kIsNeuterableBit, value)); + set_bit_field(IsNeuterable::update(bit_field(), value)); +} + + +bool JSArrayBuffer::was_neutered() { return WasNeutered::decode(bit_field()); } + + +void JSArrayBuffer::set_was_neutered(bool value) { + set_bit_field(WasNeutered::update(bit_field(), value)); +} + + +Object* JSArrayBufferView::byte_offset() const { + if (WasNeutered()) return Smi::FromInt(0); + return Object::cast(READ_FIELD(this, kByteOffsetOffset)); +} + + +void JSArrayBufferView::set_byte_offset(Object* value, WriteBarrierMode mode) { + WRITE_FIELD(this, kByteOffsetOffset, value); + CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kByteOffsetOffset, value, mode); +} + + +Object* JSArrayBufferView::byte_length() const { + if (WasNeutered()) return Smi::FromInt(0); + return Object::cast(READ_FIELD(this, kByteLengthOffset)); } -ACCESSORS(JSArrayBuffer, weak_next, Object, kWeakNextOffset) -ACCESSORS(JSArrayBuffer, weak_first_view, Object, kWeakFirstViewOffset) +void JSArrayBufferView::set_byte_length(Object* value, WriteBarrierMode mode) { + WRITE_FIELD(this, kByteLengthOffset, value); + CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kByteLengthOffset, value, mode); +} ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset) -ACCESSORS(JSArrayBufferView, byte_offset, Object, kByteOffsetOffset) -ACCESSORS(JSArrayBufferView, byte_length, Object, kByteLengthOffset) -ACCESSORS(JSArrayBufferView, weak_next, Object, kWeakNextOffset) -ACCESSORS(JSTypedArray, length, Object, kLengthOffset) +#ifdef VERIFY_HEAP +ACCESSORS(JSArrayBufferView, raw_byte_offset, Object, kByteOffsetOffset) +ACCESSORS(JSArrayBufferView, raw_byte_length, Object, kByteLengthOffset) +#endif + + +bool JSArrayBufferView::WasNeutered() const { + return JSArrayBuffer::cast(buffer())->was_neutered(); +} + + +Object* JSTypedArray::length() const { + if (WasNeutered()) return Smi::FromInt(0); + return Object::cast(READ_FIELD(this, kLengthOffset)); +} + + +void JSTypedArray::set_length(Object* value, WriteBarrierMode mode) { + WRITE_FIELD(this, kLengthOffset, value); + CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kLengthOffset, value, mode); +} + + +#ifdef VERIFY_HEAP +ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset) +#endif + ACCESSORS(JSRegExp, data, Object, kDataOffset) @@ -6996,11 +7054,12 @@ bool AccessorInfo::IsCompatibleReceiver(Object* receiver) { } -void ExecutableAccessorInfo::clear_setter() { - auto foreign = GetIsolate()->factory()->NewForeign( +// static +void ExecutableAccessorInfo::ClearSetter(Handle<ExecutableAccessorInfo> info) { + auto foreign = info->GetIsolate()->factory()->NewForeign( reinterpret_cast<v8::internal::Address>( reinterpret_cast<intptr_t>(nullptr))); - set_setter(*foreign); + info->set_setter(*foreign); } @@ -7198,6 +7257,17 @@ void JSArray::set_length(Smi* length) { } +bool JSArray::SetElementsLengthWouldNormalize( + Heap* heap, Handle<Object> new_length_handle) { + // If the new array won't fit in a some non-trivial fraction of the max old + // space size, then force it to go dictionary mode. + int max_fast_array_size = + static_cast<int>((heap->MaxOldGenerationSize() / kDoubleSize) / 4); + return new_length_handle->IsNumber() && + NumberToInt32(*new_length_handle) >= max_fast_array_size; +} + + bool JSArray::AllowsSetElementsLength() { bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray(); DCHECK(result == !HasExternalArrayElements()); @@ -7456,7 +7526,7 @@ Object* JSMapIterator::CurrentValue() { } -class String::SubStringRange::iterator FINAL { +class String::SubStringRange::iterator final { public: typedef std::forward_iterator_tag iterator_category; typedef int difference_type; |