diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2014-05-12 05:07:46 +0200 |
---|---|---|
committer | Fedor Indutny <fedor@indutny.com> | 2014-06-12 17:46:17 -0700 |
commit | 3a280b2034e3ea438cd3a2e7acd1a4cd40112ac5 (patch) | |
tree | ae194faf83fd22ad890b421c2ebd537db1a52534 /deps/v8/src/objects-inl.h | |
parent | 5413d9abe0df7e22bdb650a65f4c0ac462bbe147 (diff) | |
download | node-new-3a280b2034e3ea438cd3a2e7acd1a4cd40112ac5.tar.gz |
deps: upgrade v8 to 3.26.33
Signed-off-by: Fedor Indutny <fedor@indutny.com>
Diffstat (limited to 'deps/v8/src/objects-inl.h')
-rw-r--r-- | deps/v8/src/objects-inl.h | 1355 |
1 files changed, 666 insertions, 689 deletions
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 9d550374e0..029e80d9bb 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -1,29 +1,6 @@ // Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // // Review notes: // @@ -87,13 +64,6 @@ PropertyDetails PropertyDetails::AsDeleted() const { } -#define FIXED_TYPED_ARRAY_CAST_ACCESSOR(type) \ - template<> \ - type* type::cast(Object* object) { \ - SLOW_ASSERT(object->Is##type()); \ - return reinterpret_cast<type*>(object); \ - } - #define INT_ACCESSORS(holder, name, offset) \ int holder::name() { return READ_INT_FIELD(this, offset); } \ void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } @@ -125,6 +95,23 @@ PropertyDetails PropertyDetails::AsDeleted() const { WRITE_FIELD(this, offset, Smi::FromInt(value)); \ } +#define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \ + int holder::synchronized_##name() { \ + Object* value = ACQUIRE_READ_FIELD(this, offset); \ + return Smi::cast(value)->value(); \ + } \ + void holder::synchronized_set_##name(int value) { \ + RELEASE_WRITE_FIELD(this, offset, Smi::FromInt(value)); \ + } + +#define NOBARRIER_SMI_ACCESSORS(holder, name, offset) \ + int holder::nobarrier_##name() { \ + Object* value = NOBARRIER_READ_FIELD(this, offset); \ + return Smi::cast(value)->value(); \ + } \ + void holder::nobarrier_set_##name(int value) { \ + NOBARRIER_WRITE_FIELD(this, offset, Smi::FromInt(value)); \ + } #define BOOL_GETTER(holder, field, name, offset) \ bool holder::name() { \ @@ -170,12 +157,6 @@ bool Object::IsHeapObject() { } -bool Object::NonFailureIsHeapObject() { - ASSERT(!this->IsFailure()); - return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0; -} - - TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE) TYPE_CHECKER(Symbol, SYMBOL_TYPE) @@ -209,6 +190,11 @@ bool Object::IsSpecFunction() { } +bool Object::IsTemplateInfo() { + return IsObjectTemplateInfo() || IsFunctionTemplateInfo(); +} + + bool Object::IsInternalizedString() { if (!this->IsHeapObject()) return false; uint32_t type = HeapObject::cast(this)->map()->instance_type(); @@ -269,6 +255,7 @@ bool Object::IsExternalTwoByteString() { String::cast(this)->IsTwoByteRepresentation(); } + bool Object::HasValidElements() { // Dictionary is covered under FixedArray. return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray() || @@ -276,16 +263,17 @@ bool Object::HasValidElements() { } -MaybeObject* Object::AllocateNewStorageFor(Heap* heap, - Representation representation) { - if (representation.IsSmi() && IsUninitialized()) { - return Smi::FromInt(0); +Handle<Object> Object::NewStorageFor(Isolate* isolate, + Handle<Object> object, + Representation representation) { + if (representation.IsSmi() && object->IsUninitialized()) { + return handle(Smi::FromInt(0), isolate); } - if (!representation.IsDouble()) return this; - if (IsUninitialized()) { - return heap->AllocateHeapNumber(0); + if (!representation.IsDouble()) return object; + if (object->IsUninitialized()) { + return isolate->factory()->NewHeapNumber(0); } - return heap->AllocateHeapNumber(Number()); + return isolate->factory()->NewHeapNumber(object->Number()); } @@ -458,13 +446,34 @@ uc32 FlatStringReader::Get(int index) { } +Handle<Object> StringTableShape::AsHandle(Isolate* isolate, HashTableKey* key) { + return key->AsHandle(isolate); +} + + +Handle<Object> MapCacheShape::AsHandle(Isolate* isolate, HashTableKey* key) { + return key->AsHandle(isolate); +} + + +Handle<Object> CompilationCacheShape::AsHandle(Isolate* isolate, + HashTableKey* key) { + return key->AsHandle(isolate); +} + + +Handle<Object> CodeCacheHashTableShape::AsHandle(Isolate* isolate, + HashTableKey* key) { + return key->AsHandle(isolate); +} + template <typename Char> class SequentialStringKey : public HashTableKey { public: explicit SequentialStringKey(Vector<const Char> string, uint32_t seed) : string_(string), hash_field_(0), seed_(seed) { } - virtual uint32_t Hash() { + virtual uint32_t Hash() V8_OVERRIDE { hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(), string_.length(), seed_); @@ -475,7 +484,7 @@ class SequentialStringKey : public HashTableKey { } - virtual uint32_t HashForObject(Object* other) { + virtual uint32_t HashForObject(Object* other) V8_OVERRIDE { return String::cast(other)->Hash(); } @@ -490,11 +499,11 @@ class OneByteStringKey : public SequentialStringKey<uint8_t> { OneByteStringKey(Vector<const uint8_t> str, uint32_t seed) : SequentialStringKey<uint8_t>(str, seed) { } - virtual bool IsMatch(Object* string) { + virtual bool IsMatch(Object* string) V8_OVERRIDE { return String::cast(string)->IsOneByteEqualTo(string_); } - virtual MaybeObject* AsObject(Heap* heap); + virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE; }; @@ -509,7 +518,7 @@ class SubStringKey : public HashTableKey { ASSERT(string_->IsSeqString() || string->IsExternalString()); } - virtual uint32_t Hash() { + virtual uint32_t Hash() V8_OVERRIDE { ASSERT(length_ >= 0); ASSERT(from_ + length_ <= string_->length()); const Char* chars = GetChars() + from_; @@ -520,12 +529,12 @@ class SubStringKey : public HashTableKey { return result; } - virtual uint32_t HashForObject(Object* other) { + virtual uint32_t HashForObject(Object* other) V8_OVERRIDE { return String::cast(other)->Hash(); } - virtual bool IsMatch(Object* string); - virtual MaybeObject* AsObject(Heap* heap); + virtual bool IsMatch(Object* string) V8_OVERRIDE; + virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE; private: const Char* GetChars(); @@ -550,11 +559,11 @@ class TwoByteStringKey : public SequentialStringKey<uc16> { explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed) : SequentialStringKey<uc16>(str, seed) { } - virtual bool IsMatch(Object* string) { + virtual bool IsMatch(Object* string) V8_OVERRIDE { return String::cast(string)->IsTwoByteEqualTo(string_); } - virtual MaybeObject* AsObject(Heap* heap); + virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE; }; @@ -564,11 +573,11 @@ class Utf8StringKey : public HashTableKey { explicit Utf8StringKey(Vector<const char> string, uint32_t seed) : string_(string), hash_field_(0), seed_(seed) { } - virtual bool IsMatch(Object* string) { + virtual bool IsMatch(Object* string) V8_OVERRIDE { return String::cast(string)->IsUtf8EqualTo(string_); } - virtual uint32_t Hash() { + virtual uint32_t Hash() V8_OVERRIDE { if (hash_field_ != 0) return hash_field_ >> String::kHashShift; hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_); uint32_t result = hash_field_ >> String::kHashShift; @@ -576,15 +585,14 @@ class Utf8StringKey : public HashTableKey { return result; } - virtual uint32_t HashForObject(Object* other) { + virtual uint32_t HashForObject(Object* other) V8_OVERRIDE { return String::cast(other)->Hash(); } - virtual MaybeObject* AsObject(Heap* heap) { + virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { if (hash_field_ == 0) Hash(); - return heap->AllocateInternalizedStringFromUtf8(string_, - chars_, - hash_field_); + return isolate->factory()->NewInternalizedStringFromUtf8( + string_, chars_, hash_field_); } Vector<const char> string_; @@ -638,38 +646,6 @@ bool Object::IsFixedTypedArrayBase() { } -bool MaybeObject::IsFailure() { - return HAS_FAILURE_TAG(this); -} - - -bool MaybeObject::IsRetryAfterGC() { - return HAS_FAILURE_TAG(this) - && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC; -} - - -bool MaybeObject::IsException() { - return this == Failure::Exception(); -} - - -bool MaybeObject::IsTheHole() { - return !IsFailure() && ToObjectUnchecked()->IsTheHole(); -} - - -bool MaybeObject::IsUninitialized() { - return !IsFailure() && ToObjectUnchecked()->IsUninitialized(); -} - - -Failure* Failure::cast(MaybeObject* obj) { - ASSERT(HAS_FAILURE_TAG(obj)); - return reinterpret_cast<Failure*>(obj); -} - - bool Object::IsJSReceiver() { STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); return IsHeapObject() && @@ -694,6 +670,8 @@ bool Object::IsJSProxy() { TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE) TYPE_CHECKER(JSSet, JS_SET_TYPE) TYPE_CHECKER(JSMap, JS_MAP_TYPE) +TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE) +TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE) TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE) TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE) TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE) @@ -848,8 +826,7 @@ bool Object::IsDictionary() { bool Object::IsStringTable() { - return IsHashTable() && - this == HeapObject::cast(this)->GetHeap()->raw_unchecked_string_table(); + return IsHashTable(); } @@ -873,13 +850,23 @@ bool Object::IsJSFunctionResultCache() { bool Object::IsNormalizedMapCache() { - if (!IsFixedArray()) return false; - if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) { + return NormalizedMapCache::IsNormalizedMapCache(this); +} + + +int NormalizedMapCache::GetIndex(Handle<Map> map) { + return map->Hash() % NormalizedMapCache::kEntries; +} + + +bool NormalizedMapCache::IsNormalizedMapCache(Object* obj) { + if (!obj->IsFixedArray()) return false; + if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) { return false; } #ifdef VERIFY_HEAP if (FLAG_verify_heap) { - reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify(); + reinterpret_cast<NormalizedMapCache*>(obj)->NormalizedMapCacheVerify(); } #endif return true; @@ -911,6 +898,13 @@ bool Object::IsObjectHashTable() { } +bool Object::IsOrderedHashTable() { + return IsHeapObject() && + HeapObject::cast(this)->map() == + HeapObject::cast(this)->GetHeap()->ordered_hash_table_map(); +} + + bool Object::IsPrimitive() { return IsOddball() || IsNumber() || IsString(); } @@ -992,6 +986,11 @@ bool Object::IsTheHole() { } +bool Object::IsException() { + return IsOddball() && Oddball::cast(this)->kind() == Oddball::kException; +} + + bool Object::IsUninitialized() { return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUninitialized; } @@ -1025,8 +1024,8 @@ bool Object::IsNaN() { } -Handle<Object> Object::ToSmi(Isolate* isolate, Handle<Object> object) { - if (object->IsSmi()) return object; +MaybeHandle<Smi> Object::ToSmi(Isolate* isolate, Handle<Object> object) { + if (object->IsSmi()) return Handle<Smi>::cast(object); if (object->IsHeapNumber()) { double value = Handle<HeapNumber>::cast(object)->value(); int int_value = FastD2I(value); @@ -1034,21 +1033,14 @@ Handle<Object> Object::ToSmi(Isolate* isolate, Handle<Object> object) { return handle(Smi::FromInt(int_value), isolate); } } - return Handle<Object>(); + return Handle<Smi>(); } -// TODO(ishell): Use handlified version instead. -MaybeObject* Object::ToSmi() { - if (IsSmi()) return this; - if (IsHeapNumber()) { - double value = HeapNumber::cast(this)->value(); - int int_value = FastD2I(value); - if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { - return Smi::FromInt(int_value); - } - } - return Failure::Exception(); +MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate, + Handle<Object> object) { + return ToObject( + isolate, object, handle(isolate->context()->native_context(), isolate)); } @@ -1057,9 +1049,16 @@ bool Object::HasSpecificClassOf(String* name) { } -Handle<Object> Object::GetElement(Isolate* isolate, - Handle<Object> object, - uint32_t index) { +MaybeHandle<Object> Object::GetProperty(Handle<Object> object, + Handle<Name> name) { + PropertyAttributes attributes; + return GetPropertyWithReceiver(object, object, name, &attributes); +} + + +MaybeHandle<Object> Object::GetElement(Isolate* isolate, + Handle<Object> object, + uint32_t index) { // GetElement can trigger a getter which can cause allocation. // This was not always the case. This ASSERT is here to catch // leftover incorrect uses. @@ -1068,24 +1067,52 @@ Handle<Object> Object::GetElement(Isolate* isolate, } -Handle<Object> Object::GetElementNoExceptionThrown(Isolate* isolate, - Handle<Object> object, +MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object, + Handle<Name> name) { + uint32_t index; + Isolate* isolate = name->GetIsolate(); + if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index); + return GetProperty(object, name); +} + + +MaybeHandle<Object> Object::GetProperty(Isolate* isolate, + Handle<Object> object, + const char* name) { + Handle<String> str = isolate->factory()->InternalizeUtf8String(name); + ASSERT(!str.is_null()); +#ifdef DEBUG + uint32_t index; // Assert that the name is not an array index. + ASSERT(!str->AsArrayIndex(&index)); +#endif // DEBUG + return GetProperty(object, str); +} + + +MaybeHandle<Object> JSProxy::GetElementWithHandler(Handle<JSProxy> proxy, + Handle<Object> receiver, uint32_t index) { - Handle<Object> result = - Object::GetElementWithReceiver(isolate, object, object, index); - CHECK_NOT_EMPTY_HANDLE(isolate, result); - return result; + return GetPropertyWithHandler( + proxy, receiver, proxy->GetIsolate()->factory()->Uint32ToString(index)); } -MaybeObject* Object::GetProperty(Name* key) { - PropertyAttributes attributes; - return GetPropertyWithReceiver(this, key, &attributes); +MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, + Handle<JSReceiver> receiver, + uint32_t index, + Handle<Object> value, + StrictMode strict_mode) { + Isolate* isolate = proxy->GetIsolate(); + Handle<String> name = isolate->factory()->Uint32ToString(index); + return SetPropertyWithHandler( + proxy, receiver, name, value, NONE, strict_mode); } -MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) { - return GetPropertyWithReceiver(this, key, attributes); +bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) { + Isolate* isolate = proxy->GetIsolate(); + Handle<String> name = isolate->factory()->Uint32ToString(index); + return HasPropertyWithHandler(proxy, name); } @@ -1095,9 +1122,25 @@ MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) { #define READ_FIELD(p, offset) \ (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset))) +#define ACQUIRE_READ_FIELD(p, offset) \ + reinterpret_cast<Object*>( \ + Acquire_Load(reinterpret_cast<AtomicWord*>(FIELD_ADDR(p, offset)))) + +#define NOBARRIER_READ_FIELD(p, offset) \ + reinterpret_cast<Object*>( \ + NoBarrier_Load(reinterpret_cast<AtomicWord*>(FIELD_ADDR(p, offset)))) + #define WRITE_FIELD(p, offset, value) \ (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) +#define RELEASE_WRITE_FIELD(p, offset, value) \ + Release_Store(reinterpret_cast<AtomicWord*>(FIELD_ADDR(p, offset)), \ + reinterpret_cast<AtomicWord>(value)); + +#define NOBARRIER_WRITE_FIELD(p, offset, value) \ + NoBarrier_Store(reinterpret_cast<AtomicWord*>(FIELD_ADDR(p, offset)), \ + reinterpret_cast<AtomicWord>(value)); + #define WRITE_BARRIER(heap, object, offset, value) \ heap->incremental_marking()->RecordWrite( \ object, HeapObject::RawField(object, offset), value); \ @@ -1192,9 +1235,16 @@ MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) { #define READ_BYTE_FIELD(p, offset) \ (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset))) +#define NOBARRIER_READ_BYTE_FIELD(p, offset) \ + static_cast<byte>(NoBarrier_Load( \ + reinterpret_cast<Atomic8*>(FIELD_ADDR(p, offset))) ) + #define WRITE_BYTE_FIELD(p, offset, value) \ (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value) +#define NOBARRIER_WRITE_BYTE_FIELD(p, offset, value) \ + NoBarrier_Store(reinterpret_cast<Atomic8*>(FIELD_ADDR(p, offset)), \ + static_cast<Atomic8>(value)); Object** HeapObject::RawField(HeapObject* obj, int byte_offset) { return &READ_FIELD(obj, byte_offset); @@ -1219,62 +1269,6 @@ Smi* Smi::FromIntptr(intptr_t value) { } -Failure::Type Failure::type() const { - return static_cast<Type>(value() & kFailureTypeTagMask); -} - - -bool Failure::IsInternalError() const { - return type() == INTERNAL_ERROR; -} - - -AllocationSpace Failure::allocation_space() const { - ASSERT_EQ(RETRY_AFTER_GC, type()); - return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize) - & kSpaceTagMask); -} - - -Failure* Failure::InternalError() { - return Construct(INTERNAL_ERROR); -} - - -Failure* Failure::Exception() { - return Construct(EXCEPTION); -} - - -intptr_t Failure::value() const { - return static_cast<intptr_t>( - reinterpret_cast<uintptr_t>(this) >> kFailureTagSize); -} - - -Failure* Failure::RetryAfterGC() { - return RetryAfterGC(NEW_SPACE); -} - - -Failure* Failure::RetryAfterGC(AllocationSpace space) { - ASSERT((space & ~kSpaceTagMask) == 0); - return Construct(RETRY_AFTER_GC, space); -} - - -Failure* Failure::Construct(Type type, intptr_t value) { - uintptr_t info = - (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type; - ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info); - // Fill the unused bits with a pattern that's easy to recognize in crash - // dumps. - static const int kFailureMagicPattern = 0x0BAD0000; - return reinterpret_cast<Failure*>( - (info << kFailureTagSize) | kFailureTag | kFailureMagicPattern); -} - - bool Smi::IsValid(intptr_t value) { bool result = Internals::IsValidSmi(value); ASSERT_EQ(result, value >= kMinValue && value <= kMaxValue); @@ -1348,6 +1342,26 @@ void HeapObject::set_map(Map* value) { } +Map* HeapObject::synchronized_map() { + return synchronized_map_word().ToMap(); +} + + +void HeapObject::synchronized_set_map(Map* value) { + synchronized_set_map_word(MapWord::FromMap(value)); + if (value != NULL) { + // TODO(1600) We are passing NULL as a slot because maps can never be on + // evacuation candidate. + value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value); + } +} + + +void HeapObject::synchronized_set_map_no_write_barrier(Map* value) { + synchronized_set_map_word(MapWord::FromMap(value)); +} + + // Unsafe accessor omitting write barrier. void HeapObject::set_map_no_write_barrier(Map* value) { set_map_word(MapWord::FromMap(value)); @@ -1355,14 +1369,26 @@ void HeapObject::set_map_no_write_barrier(Map* value) { MapWord HeapObject::map_word() { - return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset))); + return MapWord( + reinterpret_cast<uintptr_t>(NOBARRIER_READ_FIELD(this, kMapOffset))); } void HeapObject::set_map_word(MapWord map_word) { - // WRITE_FIELD does not invoke write barrier, but there is no need - // here. - WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_)); + NOBARRIER_WRITE_FIELD( + this, kMapOffset, reinterpret_cast<Object*>(map_word.value_)); +} + + +MapWord HeapObject::synchronized_map_word() { + return MapWord( + reinterpret_cast<uintptr_t>(ACQUIRE_READ_FIELD(this, kMapOffset))); +} + + +void HeapObject::synchronized_set_map_word(MapWord map_word) { + RELEASE_WRITE_FIELD( + this, kMapOffset, reinterpret_cast<Object*>(map_word.value_)); } @@ -1444,11 +1470,11 @@ FixedArrayBase* JSObject::elements() { } -void JSObject::ValidateElements() { +void JSObject::ValidateElements(Handle<JSObject> object) { #ifdef ENABLE_SLOW_ASSERTS if (FLAG_enable_slow_asserts) { - ElementsAccessor* accessor = GetElementsAccessor(); - accessor->Validate(this); + ElementsAccessor* accessor = object->GetElementsAccessor(); + accessor->Validate(object); } #endif } @@ -1588,7 +1614,7 @@ inline bool AllocationSite::DigestPretenuringFeedback() { void JSObject::EnsureCanContainHeapObjectElements(Handle<JSObject> object) { - object->ValidateElements(); + JSObject::ValidateElements(object); ElementsKind elements_kind = object->map()->elements_kind(); if (!IsFastObjectElementsKind(elements_kind)) { if (IsFastHoleyElementsKind(elements_kind)) { @@ -1676,56 +1702,27 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object, } -MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate, - ElementsKind to_kind) { - Map* current_map = map(); - ElementsKind from_kind = current_map->elements_kind(); - if (from_kind == to_kind) return current_map; - - Context* native_context = isolate->context()->native_context(); - Object* maybe_array_maps = native_context->js_array_maps(); - if (maybe_array_maps->IsFixedArray()) { - FixedArray* array_maps = FixedArray::cast(maybe_array_maps); - if (array_maps->get(from_kind) == current_map) { - Object* maybe_transitioned_map = array_maps->get(to_kind); - if (maybe_transitioned_map->IsMap()) { - return Map::cast(maybe_transitioned_map); - } - } - } - - return GetElementsTransitionMapSlow(to_kind); +void JSObject::SetMapAndElements(Handle<JSObject> object, + Handle<Map> new_map, + Handle<FixedArrayBase> value) { + JSObject::MigrateToMap(object, new_map); + ASSERT((object->map()->has_fast_smi_or_object_elements() || + (*value == object->GetHeap()->empty_fixed_array())) == + (value->map() == object->GetHeap()->fixed_array_map() || + value->map() == object->GetHeap()->fixed_cow_array_map())); + ASSERT((*value == object->GetHeap()->empty_fixed_array()) || + (object->map()->has_fast_double_elements() == + value->IsFixedDoubleArray())); + object->set_elements(*value); } -void JSObject::set_map_and_elements(Map* new_map, - FixedArrayBase* value, - WriteBarrierMode mode) { - ASSERT(value->HasValidElements()); - if (new_map != NULL) { - if (mode == UPDATE_WRITE_BARRIER) { - set_map(new_map); - } else { - ASSERT(mode == SKIP_WRITE_BARRIER); - set_map_no_write_barrier(new_map); - } - } - ASSERT((map()->has_fast_smi_or_object_elements() || - (value == GetHeap()->empty_fixed_array())) == - (value->map() == GetHeap()->fixed_array_map() || - value->map() == GetHeap()->fixed_cow_array_map())); - ASSERT((value == GetHeap()->empty_fixed_array()) || - (map()->has_fast_double_elements() == value->IsFixedDoubleArray())); +void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { WRITE_FIELD(this, kElementsOffset, value); CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); } -void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { - set_map_and_elements(NULL, value, mode); -} - - void JSObject::initialize_properties() { ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); @@ -1733,50 +1730,8 @@ void JSObject::initialize_properties() { void JSObject::initialize_elements() { - if (map()->has_fast_smi_or_object_elements() || - map()->has_fast_double_elements()) { - ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); - WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); - } else if (map()->has_external_array_elements()) { - ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(map()); - ASSERT(!GetHeap()->InNewSpace(empty_array)); - WRITE_FIELD(this, kElementsOffset, empty_array); - } else if (map()->has_fixed_typed_array_elements()) { - FixedTypedArrayBase* empty_array = - GetHeap()->EmptyFixedTypedArrayForMap(map()); - ASSERT(!GetHeap()->InNewSpace(empty_array)); - WRITE_FIELD(this, kElementsOffset, empty_array); - } else { - UNREACHABLE(); - } -} - - -MaybeObject* JSObject::ResetElements() { - if (map()->is_observed()) { - // Maintain invariant that observed elements are always in dictionary mode. - SeededNumberDictionary* dictionary; - MaybeObject* maybe = SeededNumberDictionary::Allocate(GetHeap(), 0); - if (!maybe->To(&dictionary)) return maybe; - if (map() == GetHeap()->sloppy_arguments_elements_map()) { - FixedArray::cast(elements())->set(1, dictionary); - } else { - set_elements(dictionary); - } - return this; - } - - ElementsKind elements_kind = GetInitialFastElementsKind(); - if (!FLAG_smi_only_arrays) { - elements_kind = FastSmiToObjectElementsKind(elements_kind); - } - MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); - Map* map; - if (!maybe->To(&map)) return maybe; - set_map(map); - initialize_elements(); - - return this; + FixedArrayBase* elements = map()->GetInitialElements(); + WRITE_FIELD(this, kElementsOffset, elements); } @@ -1887,6 +1842,10 @@ int JSObject::GetHeaderSize() { return JSSet::kSize; case JS_MAP_TYPE: return JSMap::kSize; + case JS_SET_ITERATOR_TYPE: + return JSSetIterator::kSize; + case JS_MAP_ITERATOR_TYPE: + return JSMapIterator::kSize; case JS_WEAK_MAP_TYPE: return JSWeakMap::kSize; case JS_WEAK_SET_TYPE: @@ -1951,13 +1910,6 @@ void JSObject::SetInternalField(int index, Smi* value) { } -MaybeObject* JSObject::FastPropertyAt(Representation representation, - int index) { - Object* raw_value = RawFastPropertyAt(index); - return raw_value->AllocateNewStorageFor(GetHeap(), representation); -} - - // Access fast-case object properties at index. The use of these routines // is needed to correctly distinguish between properties stored in-object and // properties stored in the properties array. @@ -2130,6 +2082,11 @@ Object* FixedArray::get(int index) { } +Handle<Object> FixedArray::get(Handle<FixedArray> array, int index) { + return handle(array->get(index), array->GetIsolate()); +} + + bool FixedArray::is_the_hole(int index) { return get(index) == GetHeap()->the_hole_value(); } @@ -2186,20 +2143,13 @@ int64_t FixedDoubleArray::get_representation(int index) { return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize); } -MaybeObject* FixedDoubleArray::get(int index) { - if (is_the_hole(index)) { - return GetHeap()->the_hole_value(); - } else { - return GetHeap()->NumberFromDouble(get_scalar(index)); - } -} - -Handle<Object> FixedDoubleArray::get_as_handle(int index) { - if (is_the_hole(index)) { - return GetIsolate()->factory()->the_hole_value(); +Handle<Object> FixedDoubleArray::get(Handle<FixedDoubleArray> array, + int index) { + if (array->is_the_hole(index)) { + return array->GetIsolate()->factory()->the_hole_value(); } else { - return GetIsolate()->factory()->NewNumber(get_scalar(index)); + return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index)); } } @@ -2227,12 +2177,30 @@ bool FixedDoubleArray::is_the_hole(int index) { } -SMI_ACCESSORS( - ConstantPoolArray, first_code_ptr_index, kFirstCodePointerIndexOffset) -SMI_ACCESSORS( - ConstantPoolArray, first_heap_ptr_index, kFirstHeapPointerIndexOffset) -SMI_ACCESSORS( - ConstantPoolArray, first_int32_index, kFirstInt32IndexOffset) +double* FixedDoubleArray::data_start() { + return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize)); +} + + +void FixedDoubleArray::FillWithHoles(int from, int to) { + for (int i = from; i < to; i++) { + set_the_hole(i); + } +} + + +void ConstantPoolArray::set_weak_object_state( + ConstantPoolArray::WeakObjectState state) { + int old_layout_field = READ_INT_FIELD(this, kArrayLayoutOffset); + int new_layout_field = WeakObjectStateField::update(old_layout_field, state); + WRITE_INT_FIELD(this, kArrayLayoutOffset, new_layout_field); +} + + +ConstantPoolArray::WeakObjectState ConstantPoolArray::get_weak_object_state() { + int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset); + return WeakObjectStateField::decode(layout_field); +} int ConstantPoolArray::first_int64_index() { @@ -2240,6 +2208,27 @@ int ConstantPoolArray::first_int64_index() { } +int ConstantPoolArray::first_code_ptr_index() { + int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset); + return first_int64_index() + + NumberOfInt64EntriesField::decode(layout_field); +} + + +int ConstantPoolArray::first_heap_ptr_index() { + int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset); + return first_code_ptr_index() + + NumberOfCodePtrEntriesField::decode(layout_field); +} + + +int ConstantPoolArray::first_int32_index() { + int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset); + return first_heap_ptr_index() + + NumberOfHeapPtrEntriesField::decode(layout_field); +} + + int ConstantPoolArray::count_of_int64_entries() { return first_code_ptr_index(); } @@ -2260,18 +2249,20 @@ int ConstantPoolArray::count_of_int32_entries() { } -void ConstantPoolArray::SetEntryCounts(int number_of_int64_entries, - int number_of_code_ptr_entries, - int number_of_heap_ptr_entries, - int number_of_int32_entries) { - int current_index = number_of_int64_entries; - set_first_code_ptr_index(current_index); - current_index += number_of_code_ptr_entries; - set_first_heap_ptr_index(current_index); - current_index += number_of_heap_ptr_entries; - set_first_int32_index(current_index); - current_index += number_of_int32_entries; - set_length(current_index); +void ConstantPoolArray::Init(int number_of_int64_entries, + int number_of_code_ptr_entries, + int number_of_heap_ptr_entries, + int number_of_int32_entries) { + set_length(number_of_int64_entries + + number_of_code_ptr_entries + + number_of_heap_ptr_entries + + number_of_int32_entries); + int layout_field = + NumberOfInt64EntriesField::encode(number_of_int64_entries) | + NumberOfCodePtrEntriesField::encode(number_of_code_ptr_entries) | + NumberOfHeapPtrEntriesField::encode(number_of_heap_ptr_entries) | + WeakObjectStateField::encode(NO_WEAK_OBJECTS); + WRITE_INT_FIELD(this, kArrayLayoutOffset, layout_field); } @@ -2420,8 +2411,10 @@ void FixedArray::set_the_hole(int index) { } -double* FixedDoubleArray::data_start() { - return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize)); +void FixedArray::FillWithHoles(int from, int to) { + for (int i = from; i < to; i++) { + set_the_hole(i); + } } @@ -2570,15 +2563,30 @@ void Map::LookupDescriptor(JSObject* holder, void Map::LookupTransition(JSObject* holder, Name* name, LookupResult* result) { - if (HasTransitionArray()) { - TransitionArray* transition_array = transitions(); - int number = transition_array->Search(name); - if (number != TransitionArray::kNotFound) { - return result->TransitionResult( - holder, transition_array->GetTarget(number)); - } + int transition_index = this->SearchTransition(name); + if (transition_index == TransitionArray::kNotFound) return result->NotFound(); + result->TransitionResult(holder, this->GetTransition(transition_index)); +} + + +FixedArrayBase* Map::GetInitialElements() { + if (has_fast_smi_or_object_elements() || + has_fast_double_elements()) { + ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); + return GetHeap()->empty_fixed_array(); + } else if (has_external_array_elements()) { + ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this); + ASSERT(!GetHeap()->InNewSpace(empty_array)); + return empty_array; + } else if (has_fixed_typed_array_elements()) { + FixedTypedArrayBase* empty_array = + GetHeap()->EmptyFixedTypedArrayForMap(this); + ASSERT(!GetHeap()->InNewSpace(empty_array)); + return empty_array; + } else { + UNREACHABLE(); } - result->NotFound(); + return NULL; } @@ -2629,14 +2637,6 @@ void DescriptorArray::SetRepresentation(int descriptor_index, } -void DescriptorArray::InitializeRepresentations(Representation representation) { - int length = number_of_descriptors(); - for (int i = 0; i < length; i++) { - SetRepresentation(i, representation); - } -} - - Object** DescriptorArray::GetValueSlot(int descriptor_number) { ASSERT(descriptor_number < number_of_descriptors()); return RawFieldOfElementAt(ToValueIndex(descriptor_number)); @@ -2649,6 +2649,11 @@ Object* DescriptorArray::GetValue(int descriptor_number) { } +void DescriptorArray::SetValue(int descriptor_index, Object* value) { + set(ToValueIndex(descriptor_index), value); +} + + PropertyDetails DescriptorArray::GetDetails(int descriptor_number) { ASSERT(descriptor_number < number_of_descriptors()); Object* details = get(ToDetailsIndex(descriptor_number)); @@ -2667,6 +2672,12 @@ int DescriptorArray::GetFieldIndex(int descriptor_number) { } +HeapType* DescriptorArray::GetFieldType(int descriptor_number) { + ASSERT(GetDetails(descriptor_number).type() == FIELD); + return HeapType::cast(GetValue(descriptor_number)); +} + + Object* DescriptorArray::GetConstant(int descriptor_number) { return GetValue(descriptor_number); } @@ -2686,8 +2697,8 @@ AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) { void DescriptorArray::Get(int descriptor_number, Descriptor* desc) { - desc->Init(GetKey(descriptor_number), - GetValue(descriptor_number), + desc->Init(handle(GetKey(descriptor_number), GetIsolate()), + handle(GetValue(descriptor_number), GetIsolate()), GetDetails(descriptor_number)); } @@ -2700,10 +2711,10 @@ void DescriptorArray::Set(int descriptor_number, NoIncrementalWriteBarrierSet(this, ToKeyIndex(descriptor_number), - desc->GetKey()); + *desc->GetKey()); NoIncrementalWriteBarrierSet(this, ToValueIndex(descriptor_number), - desc->GetValue()); + *desc->GetValue()); NoIncrementalWriteBarrierSet(this, ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi()); @@ -2714,14 +2725,15 @@ void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { // Range check. ASSERT(descriptor_number < number_of_descriptors()); - set(ToKeyIndex(descriptor_number), desc->GetKey()); - set(ToValueIndex(descriptor_number), desc->GetValue()); + set(ToKeyIndex(descriptor_number), *desc->GetKey()); + set(ToValueIndex(descriptor_number), *desc->GetValue()); set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi()); } void DescriptorArray::Append(Descriptor* desc, const WhitenessWitness& witness) { + DisallowHeapAllocation no_gc; int descriptor_number = number_of_descriptors(); SetNumberOfDescriptors(descriptor_number + 1); Set(descriptor_number, desc, witness); @@ -2741,6 +2753,7 @@ void DescriptorArray::Append(Descriptor* desc, void DescriptorArray::Append(Descriptor* desc) { + DisallowHeapAllocation no_gc; int descriptor_number = number_of_descriptors(); SetNumberOfDescriptors(descriptor_number + 1); Set(descriptor_number, desc); @@ -2766,7 +2779,7 @@ void DescriptorArray::SwapSortedKeys(int first, int second) { } -DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array) +DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array) : marking_(array->GetHeap()->incremental_marking()) { marking_->EnterNoMarkingScope(); ASSERT(!marking_->IsMarking() || @@ -2779,8 +2792,8 @@ DescriptorArray::WhitenessWitness::~WhitenessWitness() { } -template<typename Shape, typename Key> -int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) { +template<typename Derived, typename Shape, typename Key> +int HashTable<Derived, Shape, Key>::ComputeCapacity(int at_least_space_for) { const int kMinCapacity = 32; int capacity = RoundUpToPowerOf2(at_least_space_for * 2); if (capacity < kMinCapacity) { @@ -2790,17 +2803,17 @@ int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) { } -template<typename Shape, typename Key> -int HashTable<Shape, Key>::FindEntry(Key key) { +template<typename Derived, typename Shape, typename Key> +int HashTable<Derived, Shape, Key>::FindEntry(Key key) { return FindEntry(GetIsolate(), key); } // Find entry for key otherwise return kNotFound. -template<typename Shape, typename Key> -int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) { +template<typename Derived, typename Shape, typename Key> +int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key) { uint32_t capacity = Capacity(); - uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity); + uint32_t entry = FirstProbe(HashTable::Hash(key), capacity); uint32_t count = 1; // EnsureCapacity will guarantee the hash table is never full. while (true) { @@ -2893,6 +2906,8 @@ CAST_ACCESSOR(JSProxy) CAST_ACCESSOR(JSFunctionProxy) CAST_ACCESSOR(JSSet) CAST_ACCESSOR(JSMap) +CAST_ACCESSOR(JSSetIterator) +CAST_ACCESSOR(JSMapIterator) CAST_ACCESSOR(JSWeakMap) CAST_ACCESSOR(JSWeakSet) CAST_ACCESSOR(Foreign) @@ -2925,17 +2940,22 @@ FixedTypedArray<Traits>* FixedTypedArray<Traits>::cast(Object* object) { #undef MAKE_STRUCT_CAST -template <typename Shape, typename Key> -HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { +template <typename Derived, typename Shape, typename Key> +HashTable<Derived, Shape, Key>* +HashTable<Derived, Shape, Key>::cast(Object* obj) { ASSERT(obj->IsHashTable()); return reinterpret_cast<HashTable*>(obj); } SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) +SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) + SMI_ACCESSORS(FreeSpace, size, kSizeOffset) +NOBARRIER_SMI_ACCESSORS(FreeSpace, size, kSizeOffset) SMI_ACCESSORS(String, length, kLengthOffset) +SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset) uint32_t Name::hash_field() { @@ -2961,6 +2981,17 @@ bool Name::Equals(Name* other) { } +bool Name::Equals(Handle<Name> one, Handle<Name> two) { + if (one.is_identical_to(two)) return true; + if ((one->IsInternalizedString() && two->IsInternalizedString()) || + one->IsSymbol() || two->IsSymbol()) { + return false; + } + return String::SlowEquals(Handle<String>::cast(one), + Handle<String>::cast(two)); +} + + ACCESSORS(Symbol, name, Object, kNameOffset) ACCESSORS(Symbol, flags, Smi, kFlagsOffset) BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit) @@ -2975,19 +3006,20 @@ bool String::Equals(String* other) { } -MaybeObject* String::TryFlatten(PretenureFlag pretenure) { - if (!StringShape(this).IsCons()) return this; - ConsString* cons = ConsString::cast(this); - if (cons->IsFlat()) return cons->first(); - return SlowTryFlatten(pretenure); +bool String::Equals(Handle<String> one, Handle<String> two) { + if (one.is_identical_to(two)) return true; + if (one->IsInternalizedString() && two->IsInternalizedString()) { + return false; + } + return SlowEquals(one, two); } -String* String::TryFlattenGetString(PretenureFlag pretenure) { - MaybeObject* flat = TryFlatten(pretenure); - Object* successfully_flattened; - if (!flat->ToObject(&successfully_flattened)) return this; - return String::cast(successfully_flattened); +Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { + if (!string->IsConsString()) return string; + Handle<ConsString> cons = Handle<ConsString>::cast(string); + if (cons->IsFlat()) return handle(cons->first()); + return SlowFlatten(cons, pretenure); } @@ -3044,96 +3076,60 @@ String* String::GetUnderlying() { } -template<class Visitor, class ConsOp> -void String::Visit( - String* string, - unsigned offset, - Visitor& visitor, - ConsOp& cons_op, - int32_t type, - unsigned length) { - ASSERT(length == static_cast<unsigned>(string->length())); +template<class Visitor> +ConsString* String::VisitFlat(Visitor* visitor, + String* string, + const int offset) { + int slice_offset = offset; + const int length = string->length(); ASSERT(offset <= length); - unsigned slice_offset = offset; while (true) { - ASSERT(type == string->map()->instance_type()); - + int32_t type = string->map()->instance_type(); switch (type & (kStringRepresentationMask | kStringEncodingMask)) { case kSeqStringTag | kOneByteStringTag: - visitor.VisitOneByteString( + visitor->VisitOneByteString( SeqOneByteString::cast(string)->GetChars() + slice_offset, length - offset); - return; + return NULL; case kSeqStringTag | kTwoByteStringTag: - visitor.VisitTwoByteString( + visitor->VisitTwoByteString( SeqTwoByteString::cast(string)->GetChars() + slice_offset, length - offset); - return; + return NULL; case kExternalStringTag | kOneByteStringTag: - visitor.VisitOneByteString( + visitor->VisitOneByteString( ExternalAsciiString::cast(string)->GetChars() + slice_offset, length - offset); - return; + return NULL; case kExternalStringTag | kTwoByteStringTag: - visitor.VisitTwoByteString( + visitor->VisitTwoByteString( ExternalTwoByteString::cast(string)->GetChars() + slice_offset, length - offset); - return; + return NULL; case kSlicedStringTag | kOneByteStringTag: case kSlicedStringTag | kTwoByteStringTag: { SlicedString* slicedString = SlicedString::cast(string); slice_offset += slicedString->offset(); string = slicedString->parent(); - type = string->map()->instance_type(); continue; } case kConsStringTag | kOneByteStringTag: case kConsStringTag | kTwoByteStringTag: - string = cons_op.Operate(string, &offset, &type, &length); - if (string == NULL) return; - slice_offset = offset; - ASSERT(length == static_cast<unsigned>(string->length())); - continue; + return ConsString::cast(string); default: UNREACHABLE(); - return; + return NULL; } } } -// TODO(dcarney): Remove this class after conversion to VisitFlat. -class ConsStringCaptureOp { - public: - inline ConsStringCaptureOp() : cons_string_(NULL) {} - inline String* Operate(String* string, unsigned*, int32_t*, unsigned*) { - cons_string_ = ConsString::cast(string); - return NULL; - } - ConsString* cons_string_; -}; - - -template<class Visitor> -ConsString* String::VisitFlat(Visitor* visitor, - String* string, - int offset, - int length, - int32_t type) { - ASSERT(length >= 0 && length == string->length()); - ASSERT(offset >= 0 && offset <= length); - ConsStringCaptureOp op; - Visit(string, offset, *visitor, op, type, static_cast<unsigned>(length)); - return op.cons_string_; -} - - uint16_t SeqOneByteString::SeqOneByteStringGet(int index) { ASSERT(index >= 0 && index < length()); return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); @@ -3313,12 +3309,7 @@ const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData( } -String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) { - return NULL; -} - - -unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) { +int ConsStringIteratorOp::OffsetForDepth(int depth) { return depth & kDepthMask; } @@ -3346,45 +3337,9 @@ void ConsStringIteratorOp::Pop() { } -bool ConsStringIteratorOp::HasMore() { - return depth_ != 0; -} - - -void ConsStringIteratorOp::Reset() { - depth_ = 0; -} - - -String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out, - unsigned* length_out) { - bool blew_stack = false; - String* string = NextLeaf(&blew_stack, type_out, length_out); - // String found. - if (string != NULL) { - // Verify output. - ASSERT(*length_out == static_cast<unsigned>(string->length())); - ASSERT(*type_out == string->map()->instance_type()); - return string; - } - // Traversal complete. - if (!blew_stack) return NULL; - // Restart search from root. - unsigned offset_out; - string = Search(&offset_out, type_out, length_out); - // Verify output. - ASSERT(string == NULL || offset_out == 0); - ASSERT(string == NULL || - *length_out == static_cast<unsigned>(string->length())); - ASSERT(string == NULL || *type_out == string->map()->instance_type()); - return string; -} - - uint16_t StringCharacterStream::GetNext() { ASSERT(buffer8_ != NULL && end_ != NULL); // Advance cursor if needed. - // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this. if (buffer8_ == end_) HasMore(); ASSERT(buffer8_ < end_); return is_one_byte_ ? *buffer8_++ : *buffer16_++; @@ -3393,41 +3348,39 @@ uint16_t StringCharacterStream::GetNext() { StringCharacterStream::StringCharacterStream(String* string, ConsStringIteratorOp* op, - unsigned offset) + int offset) : is_one_byte_(false), op_(op) { Reset(string, offset); } -void StringCharacterStream::Reset(String* string, unsigned offset) { - op_->Reset(); +void StringCharacterStream::Reset(String* string, int offset) { buffer8_ = NULL; end_ = NULL; - int32_t type = string->map()->instance_type(); - unsigned length = string->length(); - String::Visit(string, offset, *this, *op_, type, length); + ConsString* cons_string = String::VisitFlat(this, string, offset); + op_->Reset(cons_string, offset); + if (cons_string != NULL) { + string = op_->Next(&offset); + if (string != NULL) String::VisitFlat(this, string, offset); + } } bool StringCharacterStream::HasMore() { if (buffer8_ != end_) return true; - if (!op_->HasMore()) return false; - unsigned length; - int32_t type; - String* string = op_->ContinueOperation(&type, &length); + int offset; + String* string = op_->Next(&offset); + ASSERT_EQ(offset, 0); if (string == NULL) return false; - ASSERT(!string->IsConsString()); - ASSERT(string->length() != 0); - ConsStringNullOp null_op; - String::Visit(string, 0, *this, null_op, type, length); + String::VisitFlat(this, string); ASSERT(buffer8_ != end_); return true; } void StringCharacterStream::VisitOneByteString( - const uint8_t* chars, unsigned length) { + const uint8_t* chars, int length) { is_one_byte_ = true; buffer8_ = chars; end_ = chars + length; @@ -3435,7 +3388,7 @@ void StringCharacterStream::VisitOneByteString( void StringCharacterStream::VisitTwoByteString( - const uint16_t* chars, unsigned length) { + const uint16_t* chars, int length) { is_one_byte_ = false; buffer16_ = chars; end_ = reinterpret_cast<const uint8_t*>(chars + length); @@ -3519,8 +3472,11 @@ uint8_t ExternalUint8ClampedArray::get_scalar(int index) { } -MaybeObject* ExternalUint8ClampedArray::get(int index) { - return Smi::FromInt(static_cast<int>(get_scalar(index))); +Handle<Object> ExternalUint8ClampedArray::get( + Handle<ExternalUint8ClampedArray> array, + int index) { + return Handle<Smi>(Smi::FromInt(array->get_scalar(index)), + array->GetIsolate()); } @@ -3550,8 +3506,10 @@ int8_t ExternalInt8Array::get_scalar(int index) { } -MaybeObject* ExternalInt8Array::get(int index) { - return Smi::FromInt(static_cast<int>(get_scalar(index))); +Handle<Object> ExternalInt8Array::get(Handle<ExternalInt8Array> array, + int index) { + return Handle<Smi>(Smi::FromInt(array->get_scalar(index)), + array->GetIsolate()); } @@ -3569,8 +3527,10 @@ uint8_t ExternalUint8Array::get_scalar(int index) { } -MaybeObject* ExternalUint8Array::get(int index) { - return Smi::FromInt(static_cast<int>(get_scalar(index))); +Handle<Object> ExternalUint8Array::get(Handle<ExternalUint8Array> array, + int index) { + return Handle<Smi>(Smi::FromInt(array->get_scalar(index)), + array->GetIsolate()); } @@ -3588,8 +3548,10 @@ int16_t ExternalInt16Array::get_scalar(int index) { } -MaybeObject* ExternalInt16Array::get(int index) { - return Smi::FromInt(static_cast<int>(get_scalar(index))); +Handle<Object> ExternalInt16Array::get(Handle<ExternalInt16Array> array, + int index) { + return Handle<Smi>(Smi::FromInt(array->get_scalar(index)), + array->GetIsolate()); } @@ -3607,8 +3569,10 @@ uint16_t ExternalUint16Array::get_scalar(int index) { } -MaybeObject* ExternalUint16Array::get(int index) { - return Smi::FromInt(static_cast<int>(get_scalar(index))); +Handle<Object> ExternalUint16Array::get(Handle<ExternalUint16Array> array, + int index) { + return Handle<Smi>(Smi::FromInt(array->get_scalar(index)), + array->GetIsolate()); } @@ -3626,8 +3590,10 @@ int32_t ExternalInt32Array::get_scalar(int index) { } -MaybeObject* ExternalInt32Array::get(int index) { - return GetHeap()->NumberFromInt32(get_scalar(index)); +Handle<Object> ExternalInt32Array::get(Handle<ExternalInt32Array> array, + int index) { + return array->GetIsolate()->factory()-> + NewNumberFromInt(array->get_scalar(index)); } @@ -3645,8 +3611,10 @@ uint32_t ExternalUint32Array::get_scalar(int index) { } -MaybeObject* ExternalUint32Array::get(int index) { - return GetHeap()->NumberFromUint32(get_scalar(index)); +Handle<Object> ExternalUint32Array::get(Handle<ExternalUint32Array> array, + int index) { + return array->GetIsolate()->factory()-> + NewNumberFromUint(array->get_scalar(index)); } @@ -3664,8 +3632,9 @@ float ExternalFloat32Array::get_scalar(int index) { } -MaybeObject* ExternalFloat32Array::get(int index) { - return GetHeap()->NumberFromDouble(get_scalar(index)); +Handle<Object> ExternalFloat32Array::get(Handle<ExternalFloat32Array> array, + int index) { + return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index)); } @@ -3683,8 +3652,9 @@ double ExternalFloat64Array::get_scalar(int index) { } -MaybeObject* ExternalFloat64Array::get(int index) { - return GetHeap()->NumberFromDouble(get_scalar(index)); +Handle<Object> ExternalFloat64Array::get(Handle<ExternalFloat64Array> array, + int index) { + return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index)); } @@ -3829,83 +3799,80 @@ double FixedTypedArray<Float64ArrayTraits>::from_double(double value) { template <class Traits> -MaybeObject* FixedTypedArray<Traits>::get(int index) { - return Traits::ToObject(GetHeap(), get_scalar(index)); +Handle<Object> FixedTypedArray<Traits>::get( + Handle<FixedTypedArray<Traits> > array, + int index) { + return Traits::ToHandle(array->GetIsolate(), array->get_scalar(index)); } + template <class Traits> -MaybeObject* FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) { +Handle<Object> FixedTypedArray<Traits>::SetValue( + Handle<FixedTypedArray<Traits> > array, + uint32_t index, + Handle<Object> value) { ElementType cast_value = Traits::defaultValue(); - if (index < static_cast<uint32_t>(length())) { + if (index < static_cast<uint32_t>(array->length())) { if (value->IsSmi()) { - int int_value = Smi::cast(value)->value(); + int int_value = Handle<Smi>::cast(value)->value(); cast_value = from_int(int_value); } else if (value->IsHeapNumber()) { - double double_value = HeapNumber::cast(value)->value(); + 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. ASSERT(value->IsUndefined()); } - set(index, cast_value); + array->set(index, cast_value); } - return Traits::ToObject(GetHeap(), cast_value); -} - -template <class Traits> -Handle<Object> FixedTypedArray<Traits>::SetValue( - Handle<FixedTypedArray<Traits> > array, - uint32_t index, - Handle<Object> value) { - CALL_HEAP_FUNCTION(array->GetIsolate(), - array->SetValue(index, *value), - Object); + return Traits::ToHandle(array->GetIsolate(), cast_value); } -MaybeObject* Uint8ArrayTraits::ToObject(Heap*, uint8_t scalar) { - return Smi::FromInt(scalar); +Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) { + return handle(Smi::FromInt(scalar), isolate); } -MaybeObject* Uint8ClampedArrayTraits::ToObject(Heap*, uint8_t scalar) { - return Smi::FromInt(scalar); +Handle<Object> Uint8ClampedArrayTraits::ToHandle(Isolate* isolate, + uint8_t scalar) { + return handle(Smi::FromInt(scalar), isolate); } -MaybeObject* Int8ArrayTraits::ToObject(Heap*, int8_t scalar) { - return Smi::FromInt(scalar); +Handle<Object> Int8ArrayTraits::ToHandle(Isolate* isolate, int8_t scalar) { + return handle(Smi::FromInt(scalar), isolate); } -MaybeObject* Uint16ArrayTraits::ToObject(Heap*, uint16_t scalar) { - return Smi::FromInt(scalar); +Handle<Object> Uint16ArrayTraits::ToHandle(Isolate* isolate, uint16_t scalar) { + return handle(Smi::FromInt(scalar), isolate); } -MaybeObject* Int16ArrayTraits::ToObject(Heap*, int16_t scalar) { - return Smi::FromInt(scalar); +Handle<Object> Int16ArrayTraits::ToHandle(Isolate* isolate, int16_t scalar) { + return handle(Smi::FromInt(scalar), isolate); } -MaybeObject* Uint32ArrayTraits::ToObject(Heap* heap, uint32_t scalar) { - return heap->NumberFromUint32(scalar); +Handle<Object> Uint32ArrayTraits::ToHandle(Isolate* isolate, uint32_t scalar) { + return isolate->factory()->NewNumberFromUint(scalar); } -MaybeObject* Int32ArrayTraits::ToObject(Heap* heap, int32_t scalar) { - return heap->NumberFromInt32(scalar); +Handle<Object> Int32ArrayTraits::ToHandle(Isolate* isolate, int32_t scalar) { + return isolate->factory()->NewNumberFromInt(scalar); } -MaybeObject* Float32ArrayTraits::ToObject(Heap* heap, float scalar) { - return heap->NumberFromDouble(scalar); +Handle<Object> Float32ArrayTraits::ToHandle(Isolate* isolate, float scalar) { + return isolate->factory()->NewNumber(scalar); } -MaybeObject* Float64ArrayTraits::ToObject(Heap* heap, double scalar) { - return heap->NumberFromDouble(scalar); +Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) { + return isolate->factory()->NewNumber(scalar); } @@ -3921,7 +3888,8 @@ void Map::set_visitor_id(int id) { int Map::instance_size() { - return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2; + return NOBARRIER_READ_BYTE_FIELD( + this, kInstanceSizeOffset) << kPointerSizeLog2; } @@ -3960,7 +3928,7 @@ int HeapObject::SizeFromMap(Map* map) { return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); } if (instance_type == FREE_SPACE_TYPE) { - return reinterpret_cast<FreeSpace*>(this)->size(); + return reinterpret_cast<FreeSpace*>(this)->nobarrier_size(); } if (instance_type == STRING_TYPE || instance_type == INTERNALIZED_STRING_TYPE) { @@ -3991,7 +3959,8 @@ void Map::set_instance_size(int value) { ASSERT_EQ(0, value & (kPointerSize - 1)); value >>= kPointerSizeLog2; ASSERT(0 <= value && value < 256); - WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value)); + NOBARRIER_WRITE_BYTE_FIELD( + this, kInstanceSizeOffset, static_cast<byte>(value)); } @@ -4377,6 +4346,7 @@ bool Code::has_major_key() { kind() == LOAD_IC || kind() == KEYED_LOAD_IC || kind() == STORE_IC || + kind() == CALL_IC || kind() == KEYED_STORE_IC || kind() == TO_BOOLEAN_IC; } @@ -4559,12 +4529,41 @@ bool Code::marked_for_deoptimization() { void Code::set_marked_for_deoptimization(bool flag) { ASSERT(kind() == OPTIMIZED_FUNCTION); + ASSERT(!flag || AllowDeoptimization::IsAllowed(GetIsolate())); int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset); int updated = MarkedForDeoptimizationField::update(previous, flag); WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated); } +bool Code::is_weak_stub() { + return CanBeWeakStub() && WeakStubField::decode( + READ_UINT32_FIELD(this, kKindSpecificFlags1Offset)); +} + + +void Code::mark_as_weak_stub() { + ASSERT(CanBeWeakStub()); + int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset); + int updated = WeakStubField::update(previous, true); + WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated); +} + + +bool Code::is_invalidated_weak_stub() { + return is_weak_stub() && InvalidatedWeakStubField::decode( + READ_UINT32_FIELD(this, kKindSpecificFlags1Offset)); +} + + +void Code::mark_as_invalidated_weak_stub() { + ASSERT(is_inline_cache_stub()); + int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset); + int updated = InvalidatedWeakStubField::update(previous, true); + WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated); +} + + bool Code::is_inline_cache_stub() { Kind kind = this->kind(); switch (kind) { @@ -4677,10 +4676,9 @@ Object* Code::GetObjectFromEntryAddress(Address location_of_address) { bool Code::IsWeakObjectInOptimizedCode(Object* object) { - ASSERT(is_optimized_code()); + if (!FLAG_collect_maps) return false; if (object->IsMap()) { return Map::cast(object)->CanTransition() && - FLAG_collect_maps && FLAG_weak_embedded_maps_in_optimized_code; } if (object->IsJSObject() || @@ -4709,6 +4707,13 @@ class Code::FindAndReplacePattern { }; +bool Code::IsWeakObjectInIC(Object* object) { + return object->IsMap() && Map::cast(object)->CanTransition() && + FLAG_collect_maps && + FLAG_weak_embedded_maps_in_ic; +} + + Object* Map::prototype() { return READ_FIELD(this, kPrototypeOffset); } @@ -4723,21 +4728,17 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) { // If the descriptor is using the empty transition array, install a new empty // transition array that will have place for an element transition. -static MaybeObject* EnsureHasTransitionArray(Map* map) { - TransitionArray* transitions; - MaybeObject* maybe_transitions; +static void EnsureHasTransitionArray(Handle<Map> map) { + Handle<TransitionArray> transitions; if (!map->HasTransitionArray()) { - maybe_transitions = TransitionArray::Allocate(map->GetIsolate(), 0); - if (!maybe_transitions->To(&transitions)) return maybe_transitions; + transitions = TransitionArray::Allocate(map->GetIsolate(), 0); transitions->set_back_pointer_storage(map->GetBackPointer()); } else if (!map->transitions()->IsFullTransitionArray()) { - maybe_transitions = map->transitions()->ExtendToFullTransitionArray(); - if (!maybe_transitions->To(&transitions)) return maybe_transitions; + transitions = TransitionArray::ExtendToFullTransitionArray(map); } else { - return map; + return; } - map->set_transitions(transitions); - return transitions; + map->set_transitions(*transitions); } @@ -4765,25 +4766,11 @@ uint32_t Map::bit_field3() { } -void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { - Object* back_pointer = GetBackPointer(); - - if (Heap::ShouldZapGarbage() && HasTransitionArray()) { - ZapTransitions(); - } - - WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer); - CONDITIONAL_WRITE_BARRIER( - heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode); -} - - -void Map::AppendDescriptor(Descriptor* desc, - const DescriptorArray::WhitenessWitness& witness) { +void Map::AppendDescriptor(Descriptor* desc) { DescriptorArray* descriptors = instance_descriptors(); int number_of_own_descriptors = NumberOfOwnDescriptors(); ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); - descriptors->Append(desc, witness); + descriptors->Append(desc); SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); } @@ -4824,33 +4811,14 @@ bool Map::CanHaveMoreTransitions() { } -MaybeObject* Map::AddTransition(Name* key, - Map* target, - SimpleTransitionFlag flag) { - if (HasTransitionArray()) return transitions()->CopyInsert(key, target); - return TransitionArray::NewWith(flag, key, target, GetBackPointer()); -} - - -void Map::SetTransition(int transition_index, Map* target) { - transitions()->SetTarget(transition_index, target); -} - - Map* Map::GetTransition(int transition_index) { return transitions()->GetTarget(transition_index); } -MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { - TransitionArray* transitions; - MaybeObject* maybe_transitions = AddTransition( - GetHeap()->elements_transition_symbol(), - transitioned_map, - FULL_TRANSITION); - if (!maybe_transitions->To(&transitions)) return maybe_transitions; - set_transitions(transitions); - return transitions; +int Map::SearchTransition(Name* name) { + if (HasTransitionArray()) return transitions()->Search(name); + return TransitionArray::kNotFound; } @@ -4863,19 +4831,18 @@ FixedArray* Map::GetPrototypeTransitions() { } -MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { - MaybeObject* allow_prototype = EnsureHasTransitionArray(this); - if (allow_prototype->IsFailure()) return allow_prototype; - int old_number_of_transitions = NumberOfProtoTransitions(); +void Map::SetPrototypeTransitions( + Handle<Map> map, Handle<FixedArray> proto_transitions) { + EnsureHasTransitionArray(map); + int old_number_of_transitions = map->NumberOfProtoTransitions(); #ifdef DEBUG - if (HasPrototypeTransitions()) { - ASSERT(GetPrototypeTransitions() != proto_transitions); - ZapPrototypeTransitions(); + if (map->HasPrototypeTransitions()) { + ASSERT(map->GetPrototypeTransitions() != *proto_transitions); + map->ZapPrototypeTransitions(); } #endif - transitions()->SetPrototypeTransitions(proto_transitions); - SetNumberOfProtoTransitions(old_number_of_transitions); - return this; + map->transitions()->SetPrototypeTransitions(*proto_transitions); + map->SetNumberOfProtoTransitions(old_number_of_transitions); } @@ -4940,23 +4907,6 @@ void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { } -// Can either be Smi (no transitions), normal transition array, or a transition -// array with the header overwritten as a Smi (thus iterating). -TransitionArray* Map::unchecked_transition_array() { - Object* object = *HeapObject::RawField(this, - Map::kTransitionsOrBackPointerOffset); - TransitionArray* transition_array = static_cast<TransitionArray*>(object); - return transition_array; -} - - -HeapObject* Map::UncheckedPrototypeTransitions() { - ASSERT(HasTransitionArray()); - ASSERT(unchecked_transition_array()->HasPrototypeTransitions()); - return unchecked_transition_array()->UncheckedPrototypeTransitions(); -} - - ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) ACCESSORS(Map, constructor, Object, kConstructorOffset) @@ -4971,6 +4921,7 @@ ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset) ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset) ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset) +ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset) ACCESSORS(AccessorInfo, name, Object, kNameOffset) ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset) @@ -5082,7 +5033,6 @@ void Script::set_compilation_state(CompilationState state) { } -#ifdef ENABLE_DEBUGGER_SUPPORT ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex) ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex) ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex) @@ -5092,12 +5042,13 @@ ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex) ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex) ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex) ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex) -#endif ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset) ACCESSORS(SharedFunctionInfo, optimized_code_map, Object, kOptimizedCodeMapOffset) ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset) +ACCESSORS(SharedFunctionInfo, feedback_vector, FixedArray, + kFeedbackVectorOffset) ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset) ACCESSORS(SharedFunctionInfo, instance_class_name, Object, kInstanceClassNameOffset) @@ -5105,7 +5056,6 @@ ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset) ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset) ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset) ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset) -SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset) SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset) @@ -5160,6 +5110,8 @@ SMI_ACCESSORS(SharedFunctionInfo, compiler_hints, SMI_ACCESSORS(SharedFunctionInfo, opt_count_and_bailout_reason, kOptCountAndBailoutReasonOffset) SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset) +SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset) +SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset) #else @@ -5210,9 +5162,15 @@ PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, opt_count_and_bailout_reason, kOptCountAndBailoutReasonOffset) - PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, counters, kCountersOffset) +PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, + ast_node_count, + kAstNodeCountOffset) +PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, + profiler_ticks, + kProfilerTicksOffset) + #endif @@ -5256,12 +5214,6 @@ void SharedFunctionInfo::set_optimization_disabled(bool disable) { } -int SharedFunctionInfo::profiler_ticks() { - if (code()->kind() != Code::FUNCTION) return 0; - return code()->profiler_ticks(); -} - - StrictMode SharedFunctionInfo::strict_mode() { return BooleanBit::get(compiler_hints(), kStrictModeFunction) ? STRICT : SLOPPY; @@ -5355,6 +5307,7 @@ void SharedFunctionInfo::ReplaceCode(Code* value) { } ASSERT(code()->gc_metadata() == NULL && value->gc_metadata() == NULL); + set_code(value); } @@ -5712,6 +5665,32 @@ void JSProxy::InitializeBody(int object_size, Object* value) { ACCESSORS(JSSet, table, Object, kTableOffset) ACCESSORS(JSMap, table, Object, kTableOffset) + + +#define ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(name, type, offset) \ + template<class Derived, class TableType> \ + type* OrderedHashTableIterator<Derived, TableType>::name() { \ + return type::cast(READ_FIELD(this, offset)); \ + } \ + template<class Derived, class TableType> \ + void OrderedHashTableIterator<Derived, TableType>::set_##name( \ + type* value, WriteBarrierMode mode) { \ + WRITE_FIELD(this, offset, value); \ + CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \ + } + +ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(table, Object, kTableOffset) +ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(index, Smi, kIndexOffset) +ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(count, Smi, kCountOffset) +ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(kind, Smi, kKindOffset) +ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(next_iterator, Object, + kNextIteratorOffset) +ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(previous_iterator, Object, + kPreviousIteratorOffset) + +#undef ORDERED_HASH_TABLE_ITERATOR_ACCESSORS + + ACCESSORS(JSWeakCollection, table, Object, kTableOffset) ACCESSORS(JSWeakCollection, next, Object, kNextOffset) @@ -5733,6 +5712,11 @@ SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset) ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset) SMI_ACCESSORS(JSGeneratorObject, stack_handler_index, kStackHandlerIndexOffset) +bool JSGeneratorObject::is_suspended() { + ASSERT_LT(kGeneratorExecuting, kGeneratorClosed); + ASSERT_EQ(kGeneratorClosed, 0); + return continuation() > 0; +} JSGeneratorObject* JSGeneratorObject::cast(Object* obj) { ASSERT(obj->IsJSGeneratorObject()); @@ -5832,7 +5816,7 @@ void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) { int Code::stub_info() { ASSERT(kind() == COMPARE_IC || kind() == COMPARE_NIL_IC || - kind() == BINARY_OP_IC || kind() == LOAD_IC); + kind() == BINARY_OP_IC || kind() == LOAD_IC || kind() == CALL_IC); return Smi::cast(raw_type_feedback_info())->value(); } @@ -5843,6 +5827,7 @@ void Code::set_stub_info(int value) { kind() == BINARY_OP_IC || kind() == STUB || kind() == LOAD_IC || + kind() == CALL_IC || kind() == KEYED_LOAD_IC || kind() == STORE_IC || kind() == KEYED_STORE_IC); @@ -6121,24 +6106,6 @@ bool JSObject::HasIndexedInterceptor() { } -MaybeObject* JSObject::EnsureWritableFastElements() { - ASSERT(HasFastSmiOrObjectElements()); - FixedArray* elems = FixedArray::cast(elements()); - Isolate* isolate = GetIsolate(); - if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; - Object* writable_elems; - { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( - elems, isolate->heap()->fixed_array_map()); - if (!maybe_writable_elems->ToObject(&writable_elems)) { - return maybe_writable_elems; - } - } - set_elements(FixedArray::cast(writable_elems)); - isolate->counters()->cow_arrays_converted()->Increment(); - return writable_elems; -} - - NameDictionary* JSObject::property_dictionary() { ASSERT(!HasFastProperties()); return NameDictionary::cast(properties()); @@ -6151,6 +6118,20 @@ SeededNumberDictionary* JSObject::element_dictionary() { } +Handle<JSSetIterator> JSSetIterator::Create( + Handle<OrderedHashSet> table, + int kind) { + return CreateInternal(table->GetIsolate()->set_iterator_map(), table, kind); +} + + +Handle<JSMapIterator> JSMapIterator::Create( + Handle<OrderedHashMap> table, + int kind) { + return CreateInternal(table->GetIsolate()->map_iterator_map(), table, kind); +} + + bool Name::IsHashFieldComputed(uint32_t field) { return (field & kHashNotComputedMask) == 0; } @@ -6461,27 +6442,27 @@ bool AccessorPair::prohibits_overwriting() { } -template<typename Shape, typename Key> -void Dictionary<Shape, Key>::SetEntry(int entry, - Object* key, - Object* value) { +template<typename Derived, typename Shape, typename Key> +void Dictionary<Derived, Shape, Key>::SetEntry(int entry, + Handle<Object> key, + Handle<Object> value) { SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0))); } -template<typename Shape, typename Key> -void Dictionary<Shape, Key>::SetEntry(int entry, - Object* key, - Object* value, - PropertyDetails details) { +template<typename Derived, typename Shape, typename Key> +void Dictionary<Derived, Shape, Key>::SetEntry(int entry, + Handle<Object> key, + Handle<Object> value, + PropertyDetails details) { ASSERT(!key->IsName() || details.IsDeleted() || details.dictionary_index() > 0); - int index = HashTable<Shape, Key>::EntryToIndex(entry); + int index = DerivedHashTable::EntryToIndex(entry); DisallowHeapAllocation no_gc; WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc); - FixedArray::set(index, key, mode); - FixedArray::set(index+1, value, mode); + FixedArray::set(index, *key, mode); + FixedArray::set(index+1, *value, mode); FixedArray::set(index+2, details.AsSmi()); } @@ -6503,10 +6484,12 @@ uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key, return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0); } + uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) { return ComputeIntegerHash(key, seed); } + uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key, uint32_t seed, Object* other) { @@ -6514,12 +6497,13 @@ uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key, return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed); } -MaybeObject* NumberDictionaryShape::AsObject(Heap* heap, uint32_t key) { - return heap->NumberFromUint32(key); + +Handle<Object> NumberDictionaryShape::AsHandle(Isolate* isolate, uint32_t key) { + return isolate->factory()->NewNumberFromUint(key); } -bool NameDictionaryShape::IsMatch(Name* key, Object* other) { +bool NameDictionaryShape::IsMatch(Handle<Name> key, Object* other) { // We know that all entries in a hash table had their hash keys created. // Use that knowledge to have fast failure. if (key->Hash() != Name::cast(other)->Hash()) return false; @@ -6527,63 +6511,72 @@ bool NameDictionaryShape::IsMatch(Name* key, Object* other) { } -uint32_t NameDictionaryShape::Hash(Name* key) { +uint32_t NameDictionaryShape::Hash(Handle<Name> key) { return key->Hash(); } -uint32_t NameDictionaryShape::HashForObject(Name* key, Object* other) { +uint32_t NameDictionaryShape::HashForObject(Handle<Name> key, Object* other) { return Name::cast(other)->Hash(); } -MaybeObject* NameDictionaryShape::AsObject(Heap* heap, Name* key) { +Handle<Object> NameDictionaryShape::AsHandle(Isolate* isolate, + Handle<Name> key) { ASSERT(key->IsUniqueName()); return key; } -template <int entrysize> -bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) { +void NameDictionary::DoGenerateNewEnumerationIndices( + Handle<NameDictionary> dictionary) { + DerivedDictionary::GenerateNewEnumerationIndices(dictionary); +} + + +bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object* other) { return key->SameValue(other); } -template <int entrysize> -uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) { +uint32_t ObjectHashTableShape::Hash(Handle<Object> key) { return Smi::cast(key->GetHash())->value(); } -template <int entrysize> -uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key, - Object* other) { +uint32_t ObjectHashTableShape::HashForObject(Handle<Object> key, + Object* other) { return Smi::cast(other->GetHash())->value(); } -template <int entrysize> -MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Heap* heap, - Object* key) { +Handle<Object> ObjectHashTableShape::AsHandle(Isolate* isolate, + Handle<Object> key) { return key; } +Handle<ObjectHashTable> ObjectHashTable::Shrink( + Handle<ObjectHashTable> table, Handle<Object> key) { + return DerivedHashTable::Shrink(table, key); +} + + template <int entrysize> -bool WeakHashTableShape<entrysize>::IsMatch(Object* key, Object* other) { +bool WeakHashTableShape<entrysize>::IsMatch(Handle<Object> key, Object* other) { return key->SameValue(other); } template <int entrysize> -uint32_t WeakHashTableShape<entrysize>::Hash(Object* key) { - intptr_t hash = reinterpret_cast<intptr_t>(key); +uint32_t WeakHashTableShape<entrysize>::Hash(Handle<Object> key) { + intptr_t hash = reinterpret_cast<intptr_t>(*key); return (uint32_t)(hash & 0xFFFFFFFF); } template <int entrysize> -uint32_t WeakHashTableShape<entrysize>::HashForObject(Object* key, +uint32_t WeakHashTableShape<entrysize>::HashForObject(Handle<Object> key, Object* other) { intptr_t hash = reinterpret_cast<intptr_t>(other); return (uint32_t)(hash & 0xFFFFFFFF); @@ -6591,8 +6584,8 @@ uint32_t WeakHashTableShape<entrysize>::HashForObject(Object* key, template <int entrysize> -MaybeObject* WeakHashTableShape<entrysize>::AsObject(Heap* heap, - Object* key) { +Handle<Object> WeakHashTableShape<entrysize>::AsHandle(Isolate* isolate, + Handle<Object> key) { return key; } @@ -6654,24 +6647,6 @@ void JSArray::SetContent(Handle<JSArray> array, } -MaybeObject* FixedArray::Copy() { - if (length() == 0) return this; - return GetHeap()->CopyFixedArray(this); -} - - -MaybeObject* FixedDoubleArray::Copy() { - if (length() == 0) return this; - return GetHeap()->CopyFixedDoubleArray(this); -} - - -MaybeObject* ConstantPoolArray::Copy() { - if (length() == 0) return this; - return GetHeap()->CopyConstantPoolArray(this); -} - - Handle<Object> TypeFeedbackInfo::UninitializedSentinel(Isolate* isolate) { return isolate->factory()->uninitialized_symbol(); } @@ -6771,10 +6746,6 @@ bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) { } -ACCESSORS(TypeFeedbackInfo, feedback_vector, FixedArray, - kFeedbackVectorOffset) - - SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot) @@ -6863,11 +6834,15 @@ void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj, #undef ACCESSORS #undef ACCESSORS_TO_SMI #undef SMI_ACCESSORS +#undef SYNCHRONIZED_SMI_ACCESSORS +#undef NOBARRIER_SMI_ACCESSORS #undef BOOL_GETTER #undef BOOL_ACCESSORS #undef FIELD_ADDR #undef READ_FIELD +#undef NOBARRIER_READ_FIELD #undef WRITE_FIELD +#undef NOBARRIER_WRITE_FIELD #undef WRITE_BARRIER #undef CONDITIONAL_WRITE_BARRIER #undef READ_DOUBLE_FIELD @@ -6882,6 +6857,8 @@ void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj, #undef WRITE_SHORT_FIELD #undef READ_BYTE_FIELD #undef WRITE_BYTE_FIELD +#undef NOBARRIER_READ_BYTE_FIELD +#undef NOBARRIER_WRITE_BYTE_FIELD } } // namespace v8::internal |