Commit 08146dc0 authored by ishell's avatar ishell Committed by Commit bot

Introduced PropertyType ACCESSOR_FIELD.

Review URL: https://codereview.chromium.org/805453002

Cr-Commit-Position: refs/heads/master@{#25842}
parent 0349f7b7
...@@ -2581,6 +2581,8 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, ...@@ -2581,6 +2581,8 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
JSObject::AddProperty(to, key, constant, details.attributes()); JSObject::AddProperty(to, key, constant, details.attributes());
break; break;
} }
case ACCESSOR_FIELD:
UNREACHABLE();
case CALLBACKS: { case CALLBACKS: {
Handle<Name> key(descs->GetKey(i)); Handle<Name> key(descs->GetKey(i));
LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR); LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
...@@ -2619,6 +2621,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, ...@@ -2619,6 +2621,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
isolate()); isolate());
} }
PropertyDetails details = properties->DetailsAt(i); PropertyDetails details = properties->DetailsAt(i);
DCHECK_EQ(DATA, details.kind());
JSObject::AddProperty(to, key, value, details.attributes()); JSObject::AddProperty(to, key, value, details.attributes());
} }
} }
......
...@@ -1592,7 +1592,7 @@ Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) { ...@@ -1592,7 +1592,7 @@ Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) {
for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
PropertyDetails details = descs->GetDetails(i); PropertyDetails details = descs->GetDetails(i);
DCHECK(details.type() == CALLBACKS); // Only accessors are expected. DCHECK(details.type() == CALLBACKS); // Only accessors are expected.
PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i + 1); PropertyDetails d(details.attributes(), CALLBACKS, i + 1);
Handle<Name> name(descs->GetKey(i)); Handle<Name> name(descs->GetKey(i));
Handle<Object> value(descs->GetCallbacksObject(i), isolate()); Handle<Object> value(descs->GetCallbacksObject(i), isolate());
Handle<PropertyCell> cell = NewPropertyCell(value); Handle<PropertyCell> cell = NewPropertyCell(value);
......
...@@ -1626,50 +1626,32 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) { ...@@ -1626,50 +1626,32 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
DescriptorArray* descs = js_obj->map()->instance_descriptors(); DescriptorArray* descs = js_obj->map()->instance_descriptors();
int real_size = js_obj->map()->NumberOfOwnDescriptors(); int real_size = js_obj->map()->NumberOfOwnDescriptors();
for (int i = 0; i < real_size; i++) { for (int i = 0; i < real_size; i++) {
switch (descs->GetType(i)) { PropertyDetails details = descs->GetDetails(i);
case FIELD: { switch (details.location()) {
Representation r = descs->GetDetails(i).representation(); case IN_OBJECT: {
Representation r = details.representation();
if (r.IsSmi() || r.IsDouble()) break; if (r.IsSmi() || r.IsDouble()) break;
int index = descs->GetFieldIndex(i);
Name* k = descs->GetKey(i); Name* k = descs->GetKey(i);
if (index < js_obj->map()->inobject_properties()) { FieldIndex field_index = FieldIndex::ForDescriptor(js_obj->map(), i);
Object* value = js_obj->InObjectPropertyAt(index); Object* value = js_obj->RawFastPropertyAt(field_index);
if (k != heap_->hidden_string()) { int field_offset =
SetPropertyReference( field_index.is_inobject() ? field_index.offset() : -1;
js_obj, entry,
k, value, if (k != heap_->hidden_string()) {
NULL, SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry, k,
js_obj->GetInObjectPropertyOffset(index)); value, NULL, field_offset);
} else {
TagObject(value, "(hidden properties)");
SetInternalReference(
js_obj, entry,
"hidden_properties", value,
js_obj->GetInObjectPropertyOffset(index));
}
} else { } else {
FieldIndex field_index = TagObject(value, "(hidden properties)");
FieldIndex::ForDescriptor(js_obj->map(), i); SetInternalReference(js_obj, entry, "hidden_properties", value,
Object* value = js_obj->RawFastPropertyAt(field_index); field_offset);
if (k != heap_->hidden_string()) {
SetPropertyReference(js_obj, entry, k, value);
} else {
TagObject(value, "(hidden properties)");
SetInternalReference(js_obj, entry, "hidden_properties", value);
}
} }
break; break;
} }
case CONSTANT: case IN_DESCRIPTOR:
SetPropertyReference( SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry,
js_obj, entry, descs->GetKey(i),
descs->GetKey(i), descs->GetConstant(i)); descs->GetValue(i));
break;
case CALLBACKS:
ExtractAccessorPairProperty(
js_obj, entry,
descs->GetKey(i), descs->GetValue(i));
break; break;
} }
} }
...@@ -1689,27 +1671,30 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) { ...@@ -1689,27 +1671,30 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
SetInternalReference(js_obj, entry, "hidden_properties", value); SetInternalReference(js_obj, entry, "hidden_properties", value);
continue; continue;
} }
if (ExtractAccessorPairProperty(js_obj, entry, k, value)) continue; PropertyDetails details = dictionary->DetailsAt(i);
SetPropertyReference(js_obj, entry, Name::cast(k), value); SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry,
Name::cast(k), value);
} }
} }
} }
} }
bool V8HeapExplorer::ExtractAccessorPairProperty( void V8HeapExplorer::ExtractAccessorPairProperty(JSObject* js_obj, int entry,
JSObject* js_obj, int entry, Object* key, Object* callback_obj) { Name* key,
if (!callback_obj->IsAccessorPair()) return false; Object* callback_obj,
int field_offset) {
if (!callback_obj->IsAccessorPair()) return;
AccessorPair* accessors = AccessorPair::cast(callback_obj); AccessorPair* accessors = AccessorPair::cast(callback_obj);
SetPropertyReference(js_obj, entry, key, accessors, NULL, field_offset);
Object* getter = accessors->getter(); Object* getter = accessors->getter();
if (!getter->IsOddball()) { if (!getter->IsOddball()) {
SetPropertyReference(js_obj, entry, Name::cast(key), getter, "get %s"); SetPropertyReference(js_obj, entry, key, getter, "get %s");
} }
Object* setter = accessors->setter(); Object* setter = accessors->setter();
if (!setter->IsOddball()) { if (!setter->IsOddball()) {
SetPropertyReference(js_obj, entry, Name::cast(key), setter, "set %s"); SetPropertyReference(js_obj, entry, key, setter, "set %s");
} }
return true;
} }
...@@ -2048,6 +2033,20 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj, ...@@ -2048,6 +2033,20 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
} }
void V8HeapExplorer::SetDataOrAccessorPropertyReference(
PropertyKind kind, JSObject* parent_obj, int parent_entry,
Name* reference_name, Object* child_obj, const char* name_format_string,
int field_offset) {
if (kind == ACCESSOR) {
ExtractAccessorPairProperty(parent_obj, parent_entry, reference_name,
child_obj, field_offset);
} else {
SetPropertyReference(parent_obj, parent_entry, reference_name, child_obj,
name_format_string, field_offset);
}
}
void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
int parent_entry, int parent_entry,
Name* reference_name, Name* reference_name,
......
...@@ -381,8 +381,8 @@ class V8HeapExplorer : public HeapEntriesAllocator { ...@@ -381,8 +381,8 @@ class V8HeapExplorer : public HeapEntriesAllocator {
void ExtractFixedArrayReferences(int entry, FixedArray* array); void ExtractFixedArrayReferences(int entry, FixedArray* array);
void ExtractClosureReferences(JSObject* js_obj, int entry); void ExtractClosureReferences(JSObject* js_obj, int entry);
void ExtractPropertyReferences(JSObject* js_obj, int entry); void ExtractPropertyReferences(JSObject* js_obj, int entry);
bool ExtractAccessorPairProperty(JSObject* js_obj, int entry, void ExtractAccessorPairProperty(JSObject* js_obj, int entry, Name* key,
Object* key, Object* callback_obj); Object* callback_obj, int field_offset = -1);
void ExtractElementReferences(JSObject* js_obj, int entry); void ExtractElementReferences(JSObject* js_obj, int entry);
void ExtractInternalReferences(JSObject* js_obj, int entry); void ExtractInternalReferences(JSObject* js_obj, int entry);
...@@ -430,6 +430,12 @@ class V8HeapExplorer : public HeapEntriesAllocator { ...@@ -430,6 +430,12 @@ class V8HeapExplorer : public HeapEntriesAllocator {
Object* child, Object* child,
const char* name_format_string = NULL, const char* name_format_string = NULL,
int field_offset = -1); int field_offset = -1);
void SetDataOrAccessorPropertyReference(PropertyKind kind,
JSObject* parent_obj, int parent,
Name* reference_name, Object* child,
const char* name_format_string = NULL,
int field_offset = -1);
void SetUserGlobalReference(Object* user_global); void SetUserGlobalReference(Object* user_global);
void SetRootGcRootsReference(); void SetRootGcRootsReference();
void SetGcRootsReference(VisitorSynchronization::SyncTag tag); void SetGcRootsReference(VisitorSynchronization::SyncTag tag);
......
...@@ -63,11 +63,10 @@ LookupIterator::State LookupIterator::LookupInHolder(Map* map, ...@@ -63,11 +63,10 @@ LookupIterator::State LookupIterator::LookupInHolder(Map* map,
property_details_ = descriptors->GetDetails(number_); property_details_ = descriptors->GetDetails(number_);
} }
has_property_ = true; has_property_ = true;
switch (property_details_.type()) { switch (property_details_.kind()) {
case v8::internal::CONSTANT: case v8::internal::DATA:
case v8::internal::FIELD:
return DATA; return DATA;
case v8::internal::CALLBACKS: case v8::internal::ACCESSOR:
return ACCESSOR; return ACCESSOR;
} }
case ACCESSOR: case ACCESSOR:
......
...@@ -241,11 +241,16 @@ void JSObject::PrintProperties(std::ostream& os) { // NOLINT ...@@ -241,11 +241,16 @@ void JSObject::PrintProperties(std::ostream& os) { // NOLINT
os << " (field at offset " << index.property_index() << ")\n"; os << " (field at offset " << index.property_index() << ")\n";
break; break;
} }
case ACCESSOR_FIELD: {
FieldIndex index = FieldIndex::ForDescriptor(map(), i);
os << " (accessor at offset " << index.property_index() << ")\n";
break;
}
case CONSTANT: case CONSTANT:
os << Brief(descs->GetConstant(i)) << " (constant)\n"; os << Brief(descs->GetConstant(i)) << " (constant)\n";
break; break;
case CALLBACKS: case CALLBACKS:
os << Brief(descs->GetCallbacksObject(i)) << " (callback)\n"; os << Brief(descs->GetCallbacksObject(i)) << " (callbacks)\n";
break; break;
} }
} }
...@@ -1189,19 +1194,15 @@ void TransitionArray::PrintTransitions(std::ostream& os, ...@@ -1189,19 +1194,15 @@ void TransitionArray::PrintTransitions(std::ostream& os,
os << " (transition to Object.observe)"; os << " (transition to Object.observe)";
} else { } else {
PropertyDetails details = GetTargetDetails(key, target); PropertyDetails details = GetTargetDetails(key, target);
switch (details.type()) { os << " (transition to ";
case FIELD: { if (details.location() == IN_DESCRIPTOR) {
os << " (transition to field)"; os << "immutable ";
break; }
} os << (details.kind() == DATA ? "data" : "accessor");
case CONSTANT: if (details.location() == IN_DESCRIPTOR) {
os << " (transition to constant " << Brief(GetTargetValue(i)) << ")"; os << " " << Brief(GetTargetValue(i));
break;
case CALLBACKS:
os << " (transition to callback " << Brief(GetTargetValue(i)) << ")";
break;
} }
os << ", attrs: " << details.attributes(); os << "), attrs: " << details.attributes();
} }
os << " -> " << Brief(target) << "\n"; os << " -> " << Brief(target) << "\n";
} }
......
...@@ -2866,29 +2866,35 @@ MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { ...@@ -2866,29 +2866,35 @@ MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) {
DescriptorArray* new_descriptors = new_map->instance_descriptors(); DescriptorArray* new_descriptors = new_map->instance_descriptors();
PropertyDetails new_details = new_descriptors->GetDetails(i); PropertyDetails new_details = new_descriptors->GetDetails(i);
if (old_details.attributes() != new_details.attributes() || DCHECK_EQ(old_details.kind(), new_details.kind());
!old_details.representation().fits_into(new_details.representation())) { DCHECK_EQ(old_details.attributes(), new_details.attributes());
if (!old_details.representation().fits_into(new_details.representation())) {
return MaybeHandle<Map>(); return MaybeHandle<Map>();
} }
PropertyType new_type = new_details.type();
PropertyType old_type = old_details.type();
Object* new_value = new_descriptors->GetValue(i); Object* new_value = new_descriptors->GetValue(i);
Object* old_value = old_descriptors->GetValue(i); Object* old_value = old_descriptors->GetValue(i);
switch (new_type) { switch (new_details.type()) {
case FIELD: case FIELD: {
if ((old_type == FIELD && PropertyType old_type = old_details.type();
!HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) || if (old_type == FIELD) {
(old_type == CONSTANT && if (!HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) {
!HeapType::cast(new_value)->NowContains(old_value)) || return MaybeHandle<Map>();
(old_type == CALLBACKS && }
!HeapType::Any()->Is(HeapType::cast(new_value)))) { } else {
return MaybeHandle<Map>(); DCHECK(old_type == CONSTANT);
if (!HeapType::cast(new_value)->NowContains(old_value)) {
return MaybeHandle<Map>();
}
} }
break; break;
}
case ACCESSOR_FIELD:
DCHECK(HeapType::Any()->Is(HeapType::cast(new_value)));
break;
case CONSTANT: case CONSTANT:
case CALLBACKS: case CALLBACKS:
if (old_type != new_type || old_value != new_value) { if (old_details.location() == IN_OBJECT || old_value != new_value) {
return MaybeHandle<Map>(); return MaybeHandle<Map>();
} }
break; break;
...@@ -4364,16 +4370,15 @@ void JSObject::MigrateFastToSlow(Handle<JSObject> object, ...@@ -4364,16 +4370,15 @@ void JSObject::MigrateFastToSlow(Handle<JSObject> object,
Handle<DescriptorArray> descs(map->instance_descriptors()); Handle<DescriptorArray> descs(map->instance_descriptors());
for (int i = 0; i < real_size; i++) { for (int i = 0; i < real_size; i++) {
PropertyDetails details = descs->GetDetails(i); PropertyDetails details = descs->GetDetails(i);
Handle<Name> key(descs->GetKey(i));
switch (details.type()) { switch (details.type()) {
case CONSTANT: { case CONSTANT: {
Handle<Name> key(descs->GetKey(i));
Handle<Object> value(descs->GetConstant(i), isolate); Handle<Object> value(descs->GetConstant(i), isolate);
PropertyDetails d(details.attributes(), FIELD, i + 1); PropertyDetails d(details.attributes(), FIELD, i + 1);
dictionary = NameDictionary::Add(dictionary, key, value, d); dictionary = NameDictionary::Add(dictionary, key, value, d);
break; break;
} }
case FIELD: { case FIELD: {
Handle<Name> key(descs->GetKey(i));
FieldIndex index = FieldIndex::ForDescriptor(*map, i); FieldIndex index = FieldIndex::ForDescriptor(*map, i);
Handle<Object> value; Handle<Object> value;
if (object->IsUnboxedDoubleField(index)) { if (object->IsUnboxedDoubleField(index)) {
...@@ -4391,8 +4396,14 @@ void JSObject::MigrateFastToSlow(Handle<JSObject> object, ...@@ -4391,8 +4396,14 @@ void JSObject::MigrateFastToSlow(Handle<JSObject> object,
dictionary = NameDictionary::Add(dictionary, key, value, d); dictionary = NameDictionary::Add(dictionary, key, value, d);
break; break;
} }
case ACCESSOR_FIELD: {
FieldIndex index = FieldIndex::ForDescriptor(*map, i);
Handle<Object> value(object->RawFastPropertyAt(index), isolate);
PropertyDetails d(details.attributes(), CALLBACKS, i + 1);
dictionary = NameDictionary::Add(dictionary, key, value, d);
break;
}
case CALLBACKS: { case CALLBACKS: {
Handle<Name> key(descs->GetKey(i));
Handle<Object> value(descs->GetCallbacksObject(i), isolate); Handle<Object> value(descs->GetCallbacksObject(i), isolate);
PropertyDetails d(details.attributes(), CALLBACKS, i + 1); PropertyDetails d(details.attributes(), CALLBACKS, i + 1);
dictionary = NameDictionary::Add(dictionary, key, value, d); dictionary = NameDictionary::Add(dictionary, key, value, d);
...@@ -7069,6 +7080,7 @@ bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { ...@@ -7069,6 +7080,7 @@ bool DescriptorArray::CanHoldValue(int descriptor, Object* value) {
value->FitsRepresentation(details.representation())); value->FitsRepresentation(details.representation()));
return GetConstant(descriptor) == value; return GetConstant(descriptor) == value;
case ACCESSOR_FIELD:
case CALLBACKS: case CALLBACKS:
return false; return false;
} }
...@@ -7194,7 +7206,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, ...@@ -7194,7 +7206,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map,
int descriptor = transition->LastAdded(); int descriptor = transition->LastAdded();
DCHECK(descriptors->GetKey(descriptor)->Equals(*name)); DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type()); DCHECK_EQ(ACCESSOR, descriptors->GetDetails(descriptor).kind());
DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
......
...@@ -57,6 +57,7 @@ enum PropertyLocation { IN_OBJECT = 0, IN_DESCRIPTOR = 1 }; ...@@ -57,6 +57,7 @@ enum PropertyLocation { IN_OBJECT = 0, IN_DESCRIPTOR = 1 };
enum PropertyType { enum PropertyType {
FIELD = (IN_OBJECT << 1) | DATA, FIELD = (IN_OBJECT << 1) | DATA,
CONSTANT = (IN_DESCRIPTOR << 1) | DATA, CONSTANT = (IN_DESCRIPTOR << 1) | DATA,
ACCESSOR_FIELD = (IN_OBJECT << 1) | ACCESSOR,
CALLBACKS = (IN_DESCRIPTOR << 1) | ACCESSOR CALLBACKS = (IN_DESCRIPTOR << 1) | ACCESSOR
}; };
......
...@@ -51,18 +51,11 @@ struct FastPropertyDetails { ...@@ -51,18 +51,11 @@ struct FastPropertyDetails {
// Outputs PropertyDetails as a dictionary details. // Outputs PropertyDetails as a dictionary details.
std::ostream& operator<<(std::ostream& os, const PropertyDetails& details) { std::ostream& operator<<(std::ostream& os, const PropertyDetails& details) {
os << "("; os << "(";
switch (details.type()) { if (details.location() == IN_DESCRIPTOR) {
case FIELD: os << "immutable ";
os << "normal: ";
break;
case CALLBACKS:
os << "callbacks: ";
break;
case CONSTANT:
UNREACHABLE();
break;
} }
return os << " dictionary_index: " << details.dictionary_index() os << (details.kind() == DATA ? "data" : "accessor");
return os << ", dictionary_index: " << details.dictionary_index()
<< ", attrs: " << details.attributes() << ")"; << ", attrs: " << details.attributes() << ")";
} }
...@@ -72,20 +65,16 @@ std::ostream& operator<<(std::ostream& os, ...@@ -72,20 +65,16 @@ std::ostream& operator<<(std::ostream& os,
const FastPropertyDetails& details_fast) { const FastPropertyDetails& details_fast) {
const PropertyDetails& details = details_fast.details; const PropertyDetails& details = details_fast.details;
os << "("; os << "(";
switch (details.type()) { if (details.location() == IN_DESCRIPTOR) {
case CONSTANT: os << "immutable ";
os << "constant: p: " << details.pointer();
break;
case FIELD:
os << "field: " << details.representation().Mnemonic()
<< ", field_index: " << details.field_index()
<< ", p: " << details.pointer();
break;
case CALLBACKS:
os << "callbacks: p: " << details.pointer();
break;
} }
return os << ", attrs: " << details.attributes() << ")"; os << (details.kind() == DATA ? "data" : "accessor");
if (details.location() == IN_OBJECT) {
os << ": " << details.representation().Mnemonic()
<< ", field_index: " << details.field_index();
}
return os << ", p: " << details.pointer()
<< ", attrs: " << details.attributes() << ")";
} }
......
...@@ -1916,6 +1916,47 @@ TEST(FastCaseAccessors) { ...@@ -1916,6 +1916,47 @@ TEST(FastCaseAccessors) {
} }
TEST(FastCaseRedefinedAccessors) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
CompileRun(
"var obj1 = {};\n"
"Object.defineProperty(obj1, 'prop', { "
" get: function() { return 42; },\n"
" set: function(value) { return this.prop_ = value; },\n"
" configurable: true,\n"
" enumerable: true,\n"
"});\n"
"Object.defineProperty(obj1, 'prop', { "
" get: function() { return 153; },\n"
" set: function(value) { return this.prop_ = value; },\n"
" configurable: true,\n"
" enumerable: true,\n"
"});\n");
v8::Local<v8::Object> js_global =
env->Global()->GetPrototype().As<v8::Object>();
i::Handle<i::JSObject> js_obj1 =
v8::Utils::OpenHandle(*js_global->Get(v8_str("obj1")).As<v8::Object>());
USE(js_obj1);
const v8::HeapSnapshot* snapshot =
heap_profiler->TakeHeapSnapshot(v8_str("fastCaseAccessors"));
CHECK(ValidateSnapshot(snapshot));
const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
CHECK_NE(NULL, global);
const v8::HeapGraphNode* obj1 =
GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1");
CHECK_NE(NULL, obj1);
const v8::HeapGraphNode* func;
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get prop");
CHECK_NE(NULL, func);
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set prop");
CHECK_NE(NULL, func);
}
TEST(SlowCaseAccessors) { TEST(SlowCaseAccessors) {
LocalContext env; LocalContext env;
v8::HandleScope scope(env->GetIsolate()); v8::HandleScope scope(env->GetIsolate());
......
...@@ -30,6 +30,24 @@ static void ConnectTransition(Handle<Map> parent, ...@@ -30,6 +30,24 @@ static void ConnectTransition(Handle<Map> parent,
} }
static void CheckPropertyDetailsFieldsConsistency(PropertyType type,
PropertyKind kind,
PropertyLocation location) {
int type_value = PropertyDetails::TypeField::encode(type);
int kind_location_value = PropertyDetails::KindField::encode(kind) |
PropertyDetails::LocationField::encode(location);
CHECK_EQ(type_value, kind_location_value);
}
TEST(PropertyDetailsFieldsConsistency) {
CheckPropertyDetailsFieldsConsistency(FIELD, DATA, IN_OBJECT);
CheckPropertyDetailsFieldsConsistency(CONSTANT, DATA, IN_DESCRIPTOR);
CheckPropertyDetailsFieldsConsistency(ACCESSOR_FIELD, ACCESSOR, IN_OBJECT);
CheckPropertyDetailsFieldsConsistency(CALLBACKS, ACCESSOR, IN_DESCRIPTOR);
}
TEST(TransitionArray_SimpleFieldTransitions) { TEST(TransitionArray_SimpleFieldTransitions) {
CcTest::InitializeVM(); CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment