summaryrefslogtreecommitdiffstats
path: root/src/objects-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/objects-inl.h')
-rw-r--r--src/objects-inl.h193
1 files changed, 159 insertions, 34 deletions
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 101096d6..c70ab022 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1167,7 +1167,8 @@ HeapObject* JSObject::elements() {
void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
ASSERT(map()->has_fast_elements() ==
- (value->map() == Heap::fixed_array_map()));
+ (value->map() == Heap::fixed_array_map() ||
+ value->map() == Heap::fixed_cow_array_map()));
// In the assert below Dictionary is covered under FixedArray.
ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
value->IsExternalArray());
@@ -1397,6 +1398,7 @@ Object* FixedArray::get(int index) {
void FixedArray::set(int index, Smi* value) {
+ ASSERT(map() != Heap::fixed_cow_array_map());
ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
int offset = kHeaderSize + index * kPointerSize;
WRITE_FIELD(this, offset, value);
@@ -1404,6 +1406,7 @@ void FixedArray::set(int index, Smi* value) {
void FixedArray::set(int index, Object* value) {
+ ASSERT(map() != Heap::fixed_cow_array_map());
ASSERT(index >= 0 && index < this->length());
int offset = kHeaderSize + index * kPointerSize;
WRITE_FIELD(this, offset, value);
@@ -1420,6 +1423,7 @@ WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
void FixedArray::set(int index,
Object* value,
WriteBarrierMode mode) {
+ ASSERT(map() != Heap::fixed_cow_array_map());
ASSERT(index >= 0 && index < this->length());
int offset = kHeaderSize + index * kPointerSize;
WRITE_FIELD(this, offset, value);
@@ -1428,6 +1432,7 @@ void FixedArray::set(int index,
void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
+ ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map());
ASSERT(index >= 0 && index < array->length());
ASSERT(!Heap::InNewSpace(value));
WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
@@ -1435,6 +1440,7 @@ void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
void FixedArray::set_undefined(int index) {
+ ASSERT(map() != Heap::fixed_cow_array_map());
ASSERT(index >= 0 && index < this->length());
ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
@@ -1443,6 +1449,7 @@ void FixedArray::set_undefined(int index) {
void FixedArray::set_null(int index) {
+ ASSERT(map() != Heap::fixed_cow_array_map());
ASSERT(index >= 0 && index < this->length());
ASSERT(!Heap::InNewSpace(Heap::null_value()));
WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
@@ -1450,12 +1457,27 @@ void FixedArray::set_null(int index) {
void FixedArray::set_the_hole(int index) {
+ ASSERT(map() != Heap::fixed_cow_array_map());
ASSERT(index >= 0 && index < this->length());
ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
}
+void FixedArray::set_unchecked(int index, Smi* value) {
+ ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
+ int offset = kHeaderSize + index * kPointerSize;
+ WRITE_FIELD(this, offset, value);
+}
+
+
+void FixedArray::set_null_unchecked(int index) {
+ ASSERT(index >= 0 && index < this->length());
+ ASSERT(!Heap::InNewSpace(Heap::null_value()));
+ WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
+}
+
+
Object** FixedArray::data_start() {
return HeapObject::RawField(this, kHeaderSize);
}
@@ -1493,6 +1515,16 @@ int DescriptorArray::Search(String* name) {
}
+int DescriptorArray::SearchWithCache(String* name) {
+ int number = DescriptorLookupCache::Lookup(this, name);
+ if (number == DescriptorLookupCache::kAbsent) {
+ number = Search(name);
+ DescriptorLookupCache::Update(this, name, number);
+ }
+ return number;
+}
+
+
String* DescriptorArray::GetKey(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
return String::cast(get(ToKeyIndex(descriptor_number)));
@@ -2060,21 +2092,8 @@ void ExternalFloatArray::set(int index, float value) {
ptr[index] = value;
}
-inline Scavenger Map::scavenger() {
- Scavenger callback = reinterpret_cast<Scavenger>(
- READ_INTPTR_FIELD(this, kScavengerCallbackOffset));
-
- ASSERT(callback == Heap::GetScavenger(instance_type(),
- instance_size()));
- return callback;
-}
-
-inline void Map::set_scavenger(Scavenger callback) {
- WRITE_INTPTR_FIELD(this,
- kScavengerCallbackOffset,
- reinterpret_cast<intptr_t>(callback));
-}
+INT_ACCESSORS(Map, visitor_id, kScavengerCallbackOffset)
int Map::instance_size() {
return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
@@ -2099,7 +2118,7 @@ int HeapObject::SizeFromMap(Map* map) {
(kStringTag | kConsStringTag) ||
instance_type == JS_ARRAY_TYPE) return map->instance_size();
if (instance_type == FIXED_ARRAY_TYPE) {
- return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
+ return FixedArray::BodyDescriptor::SizeOf(map, this);
}
if (instance_type == BYTE_ARRAY_TYPE) {
return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
@@ -2401,6 +2420,7 @@ Object* Map::GetFastElementsMap() {
if (obj->IsFailure()) return obj;
Map* new_map = Map::cast(obj);
new_map->set_has_fast_elements(true);
+ Counters::map_slow_to_fast_elements.Increment();
return new_map;
}
@@ -2411,6 +2431,7 @@ Object* Map::GetSlowElementsMap() {
if (obj->IsFailure()) return obj;
Map* new_map = Map::cast(obj);
new_map->set_has_fast_elements(false);
+ Counters::map_fast_to_slow_elements.Increment();
return new_map;
}
@@ -2542,6 +2563,7 @@ BOOL_ACCESSORS(SharedFunctionInfo,
allows_lazy_compilation,
kAllowLazyCompilation)
+
#if V8_HOST_ARCH_32_BIT
SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
@@ -2641,6 +2663,11 @@ Code* SharedFunctionInfo::code() {
}
+Code* SharedFunctionInfo::unchecked_code() {
+ return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
+}
+
+
void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kCodeOffset, value);
CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
@@ -2661,8 +2688,7 @@ void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
bool SharedFunctionInfo::is_compiled() {
- // TODO(1242782): Create a code kind for uncompiled code.
- return code()->kind() != Code::STUB;
+ return code() != Builtins::builtin(Builtins::LazyCompile);
}
@@ -2688,18 +2714,36 @@ int SharedFunctionInfo::custom_call_generator_id() {
}
+int SharedFunctionInfo::code_age() {
+ return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
+}
+
+
+void SharedFunctionInfo::set_code_age(int code_age) {
+ set_compiler_hints(compiler_hints() |
+ ((code_age & kCodeAgeMask) << kCodeAgeShift));
+}
+
+
bool JSFunction::IsBuiltin() {
return context()->global()->IsJSBuiltinsObject();
}
Code* JSFunction::code() {
- return shared()->code();
+ return Code::cast(READ_FIELD(this, kCodeOffset));
+}
+
+
+Code* JSFunction::unchecked_code() {
+ return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
}
void JSFunction::set_code(Code* value) {
- shared()->set_code(value);
+ // Skip the write barrier because code is never in new space.
+ ASSERT(!Heap::InNewSpace(value));
+ WRITE_FIELD(this, kCodeOffset, value);
}
@@ -2713,6 +2757,12 @@ Object* JSFunction::unchecked_context() {
}
+SharedFunctionInfo* JSFunction::unchecked_shared() {
+ return reinterpret_cast<SharedFunctionInfo*>(
+ READ_FIELD(this, kSharedFunctionInfoOffset));
+}
+
+
void JSFunction::set_context(Object* value) {
ASSERT(value == Heap::undefined_value() || value->IsContext());
WRITE_FIELD(this, kContextOffset, value);
@@ -2771,7 +2821,7 @@ bool JSFunction::should_have_prototype() {
bool JSFunction::is_compiled() {
- return shared()->is_compiled();
+ return code() != Builtins::builtin(Builtins::LazyCompile);
}
@@ -2818,12 +2868,6 @@ void Proxy::set_proxy(Address value) {
}
-void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
- visitor->VisitExternalReference(
- reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
-}
-
-
ACCESSORS(JSValue, value, Object, kValueOffset)
@@ -2936,18 +2980,18 @@ void JSRegExp::SetDataAt(int index, Object* value) {
JSObject::ElementsKind JSObject::GetElementsKind() {
+ if (map()->has_fast_elements()) {
+ ASSERT(elements()->map() == Heap::fixed_array_map() ||
+ elements()->map() == Heap::fixed_cow_array_map());
+ return FAST_ELEMENTS;
+ }
HeapObject* array = elements();
if (array->IsFixedArray()) {
- // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
- if (array->map() == Heap::fixed_array_map()) {
- ASSERT(map()->has_fast_elements());
- return FAST_ELEMENTS;
- }
+ // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
+ // FixedArray, but FAST_ELEMENTS is already handled above.
ASSERT(array->IsDictionary());
- ASSERT(!map()->has_fast_elements());
return DICTIONARY_ELEMENTS;
}
- ASSERT(!map()->has_fast_elements());
if (array->IsExternalArray()) {
switch (array->map()->instance_type()) {
case EXTERNAL_BYTE_ARRAY_TYPE:
@@ -3050,6 +3094,19 @@ bool JSObject::AllowsSetElementsLength() {
}
+Object* JSObject::EnsureWritableFastElements() {
+ ASSERT(HasFastElements());
+ FixedArray* elems = FixedArray::cast(elements());
+ if (elems->map() != Heap::fixed_cow_array_map()) return elems;
+ Object* writable_elems = Heap::CopyFixedArray(elems);
+ if (writable_elems->IsFailure()) return writable_elems;
+ FixedArray::cast(writable_elems)->set_map(Heap::fixed_array_map());
+ set_elements(FixedArray::cast(writable_elems));
+ Counters::cow_arrays_converted.Increment();
+ return writable_elems;
+}
+
+
StringDictionary* JSObject::property_dictionary() {
ASSERT(!HasFastProperties());
return StringDictionary::cast(properties());
@@ -3307,6 +3364,74 @@ Object* FixedArray::Copy() {
}
+int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
+ return map->instance_size();
+}
+
+
+void Proxy::ProxyIterateBody(ObjectVisitor* v) {
+ v->VisitExternalReference(
+ reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
+}
+
+
+template<typename StaticVisitor>
+void Proxy::ProxyIterateBody() {
+ StaticVisitor::VisitExternalReference(
+ reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
+}
+
+
+void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
+ typedef v8::String::ExternalAsciiStringResource Resource;
+ v->VisitExternalAsciiString(
+ reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
+}
+
+
+template<typename StaticVisitor>
+void ExternalAsciiString::ExternalAsciiStringIterateBody() {
+ typedef v8::String::ExternalAsciiStringResource Resource;
+ StaticVisitor::VisitExternalAsciiString(
+ reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
+}
+
+
+void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
+ typedef v8::String::ExternalStringResource Resource;
+ v->VisitExternalTwoByteString(
+ reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
+}
+
+
+template<typename StaticVisitor>
+void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
+ typedef v8::String::ExternalStringResource Resource;
+ StaticVisitor::VisitExternalTwoByteString(
+ reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
+}
+
+#define SLOT_ADDR(obj, offset) \
+ reinterpret_cast<Object**>((obj)->address() + offset)
+
+template<int start_offset, int end_offset, int size>
+void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
+ HeapObject* obj,
+ ObjectVisitor* v) {
+ v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
+}
+
+
+template<int start_offset>
+void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
+ int object_size,
+ ObjectVisitor* v) {
+ v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
+}
+
+#undef SLOT_ADDR
+
+
#undef CAST_ACCESSOR
#undef INT_ACCESSORS
#undef SMI_ACCESSORS