summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects-inl.h
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2014-05-12 05:07:46 +0200
committerFedor Indutny <fedor@indutny.com>2014-06-12 17:46:17 -0700
commit3a280b2034e3ea438cd3a2e7acd1a4cd40112ac5 (patch)
treeae194faf83fd22ad890b421c2ebd537db1a52534 /deps/v8/src/objects-inl.h
parent5413d9abe0df7e22bdb650a65f4c0ac462bbe147 (diff)
downloadnode-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.h1355
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