From: danno@chromium.org Date: Fri, 9 Sep 2011 14:47:37 +0000 (+0000) Subject: Key external array map transitions on ElementsKind instead of ExternalArrayType X-Git-Tag: upstream/4.7.83~18512 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ab26d8356c1535a156991f8eea4370e595398f91;p=platform%2Fupstream%2Fv8.git Key external array map transitions on ElementsKind instead of ExternalArrayType R=jkummrow@chromium.org BUG=none TEST=none Review URL: http://codereview.chromium.org/7787007 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9214 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/api.cc b/src/api.cc index 26558c4..5c8a314 100644 --- a/src/api.cc +++ b/src/api.cc @@ -3266,6 +3266,42 @@ bool v8::Object::DeleteHiddenValue(v8::Handle key) { namespace { +static i::ElementsKind GetElementsKindFromExternalArrayType( + ExternalArrayType array_type) { + switch (array_type) { + case kExternalByteArray: + return i::EXTERNAL_BYTE_ELEMENTS; + break; + case kExternalUnsignedByteArray: + return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS; + break; + case kExternalShortArray: + return i::EXTERNAL_SHORT_ELEMENTS; + break; + case kExternalUnsignedShortArray: + return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS; + break; + case kExternalIntArray: + return i::EXTERNAL_INT_ELEMENTS; + break; + case kExternalUnsignedIntArray: + return i::EXTERNAL_UNSIGNED_INT_ELEMENTS; + break; + case kExternalFloatArray: + return i::EXTERNAL_FLOAT_ELEMENTS; + break; + case kExternalDoubleArray: + return i::EXTERNAL_DOUBLE_ELEMENTS; + break; + case kExternalPixelArray: + return i::EXTERNAL_PIXEL_ELEMENTS; + break; + } + UNREACHABLE(); + return i::DICTIONARY_ELEMENTS; +} + + void PrepareExternalArrayElements(i::Handle object, void* data, ExternalArrayType array_type, @@ -3284,9 +3320,9 @@ void PrepareExternalArrayElements(i::Handle object, elements->map() != isolate->heap()->MapForExternalArrayType(array_type); if (cant_reuse_map) { i::Handle external_array_map = - isolate->factory()->GetExternalArrayElementsMap( + isolate->factory()->GetElementsTransitionMap( i::Handle(object->map()), - array_type, + GetElementsKindFromExternalArrayType(array_type), object->HasFastProperties()); object->set_map(*external_array_map); } @@ -3348,6 +3384,7 @@ int v8::Object::GetIndexedPropertiesPixelDataLength() { } } + void v8::Object::SetIndexedPropertiesToExternalArrayData( void* data, ExternalArrayType array_type, diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 27b77de..f07e625 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -2062,7 +2062,7 @@ void Genesis::TransferNamedProperties(Handle from, break; } case MAP_TRANSITION: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: case CONSTANT_TRANSITION: case NULL_DESCRIPTOR: // Ignore non-properties. diff --git a/src/factory.cc b/src/factory.cc index ee5c37b..ad6d34b 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -465,13 +465,13 @@ Handle Factory::GetSlowElementsMap(Handle src) { } -Handle Factory::GetExternalArrayElementsMap( +Handle Factory::GetElementsTransitionMap( Handle src, - ExternalArrayType array_type, + ElementsKind elements_kind, bool safe_to_add_transition) { CALL_HEAP_FUNCTION(isolate(), - src->GetExternalArrayElementsMap(array_type, - safe_to_add_transition), + src->GetElementsTransitionMap(elements_kind, + safe_to_add_transition), Map); } diff --git a/src/factory.h b/src/factory.h index a69b05b..c748d46 100644 --- a/src/factory.h +++ b/src/factory.h @@ -219,9 +219,9 @@ class Factory { Handle GetSlowElementsMap(Handle map); - Handle GetExternalArrayElementsMap(Handle map, - ExternalArrayType array_type, - bool safe_to_add_transition); + Handle GetElementsTransitionMap(Handle map, + ElementsKind elements_kind, + bool safe_to_add_transition); Handle CopyFixedArray(Handle array); diff --git a/src/objects-inl.h b/src/objects-inl.h index 0ddf5b7..6bf4325 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -2000,7 +2000,7 @@ bool DescriptorArray::IsProperty(int descriptor_number) { bool DescriptorArray::IsTransition(int descriptor_number) { PropertyType t = GetType(descriptor_number); return t == MAP_TRANSITION || t == CONSTANT_TRANSITION || - t == EXTERNAL_ARRAY_TRANSITION; + t == ELEMENTS_TRANSITION; } diff --git a/src/objects.cc b/src/objects.cc index c77a432..93e1f5a 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -591,7 +591,7 @@ MaybeObject* Object::GetProperty(Object* receiver, return holder->GetPropertyWithInterceptor(recvr, name, attributes); } case MAP_TRANSITION: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: case CONSTANT_TRANSITION: case NULL_DESCRIPTOR: break; @@ -1435,13 +1435,12 @@ MaybeObject* JSObject::AddFastProperty(String* name, // it's unrelated to properties. int descriptor_index = old_descriptors->Search(name); - // External array transitions are stored in the descriptor for property "", - // which is not a identifier and should have forced a switch to slow - // properties above. + // Element transitions are stored in the descriptor for property "", which is + // not a identifier and should have forced a switch to slow properties above. ASSERT(descriptor_index == DescriptorArray::kNotFound || - old_descriptors->GetType(descriptor_index) != EXTERNAL_ARRAY_TRANSITION); + old_descriptors->GetType(descriptor_index) != ELEMENTS_TRANSITION); bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound || - old_descriptors->GetType(descriptor_index) == EXTERNAL_ARRAY_TRANSITION; + old_descriptors->GetType(descriptor_index) == ELEMENTS_TRANSITION; bool allow_map_transition = can_insert_transition && (isolate->context()->global_context()->object_function()->map() != map()); @@ -1989,61 +1988,25 @@ void Map::LookupInDescriptors(JSObject* holder, } -static ElementsKind GetElementsKindFromExternalArrayType( - ExternalArrayType array_type) { - switch (array_type) { - case kExternalByteArray: - return EXTERNAL_BYTE_ELEMENTS; - break; - case kExternalUnsignedByteArray: - return EXTERNAL_UNSIGNED_BYTE_ELEMENTS; - break; - case kExternalShortArray: - return EXTERNAL_SHORT_ELEMENTS; - break; - case kExternalUnsignedShortArray: - return EXTERNAL_UNSIGNED_SHORT_ELEMENTS; - break; - case kExternalIntArray: - return EXTERNAL_INT_ELEMENTS; - break; - case kExternalUnsignedIntArray: - return EXTERNAL_UNSIGNED_INT_ELEMENTS; - break; - case kExternalFloatArray: - return EXTERNAL_FLOAT_ELEMENTS; - break; - case kExternalDoubleArray: - return EXTERNAL_DOUBLE_ELEMENTS; - break; - case kExternalPixelArray: - return EXTERNAL_PIXEL_ELEMENTS; - break; - } - UNREACHABLE(); - return DICTIONARY_ELEMENTS; -} - - -MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, - bool safe_to_add_transition) { +MaybeObject* Map::GetElementsTransitionMap(ElementsKind elements_kind, + bool safe_to_add_transition) { Heap* current_heap = heap(); DescriptorArray* descriptors = instance_descriptors(); - String* external_array_sentinel_name = current_heap->empty_symbol(); + String* elements_transition_sentinel_name = current_heap->empty_symbol(); if (safe_to_add_transition) { // It's only safe to manipulate the descriptor array if it would be // safe to add a transition. ASSERT(!is_shared()); // no transitions can be added to shared maps. - // Check if the external array transition already exists. + // Check if the elements transition already exists. DescriptorLookupCache* cache = current_heap->isolate()->descriptor_lookup_cache(); - int index = cache->Lookup(descriptors, external_array_sentinel_name); + int index = cache->Lookup(descriptors, elements_transition_sentinel_name); if (index == DescriptorLookupCache::kAbsent) { - index = descriptors->Search(external_array_sentinel_name); + index = descriptors->Search(elements_transition_sentinel_name); cache->Update(descriptors, - external_array_sentinel_name, + elements_transition_sentinel_name, index); } @@ -2051,8 +2014,8 @@ MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, // return it. if (index != DescriptorArray::kNotFound) { PropertyDetails details(PropertyDetails(descriptors->GetDetails(index))); - if (details.type() == EXTERNAL_ARRAY_TRANSITION && - details.array_type() == array_type) { + if (details.type() == ELEMENTS_TRANSITION && + details.elements_kind() == elements_kind) { return descriptors->GetValue(index); } else { safe_to_add_transition = false; @@ -2060,28 +2023,29 @@ MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, } } - // No transition to an existing external array map. Make a new one. + // No transition to an existing map for the given ElementsKind. Make a new + // one. Object* obj; { MaybeObject* maybe_map = CopyDropTransitions(); if (!maybe_map->ToObject(&obj)) return maybe_map; } Map* new_map = Map::cast(obj); - new_map->set_elements_kind(GetElementsKindFromExternalArrayType(array_type)); + new_map->set_elements_kind(elements_kind); GetIsolate()->counters()->map_to_external_array_elements()->Increment(); // Only remember the map transition if the object's map is NOT equal to the // global object_function's map and there is not an already existing - // non-matching external array transition. + // non-matching element transition. bool allow_map_transition = safe_to_add_transition && (GetIsolate()->context()->global_context()->object_function()->map() != map()); if (allow_map_transition) { // Allocate new instance descriptors for the old map with map transition. - ExternalArrayTransitionDescriptor desc(external_array_sentinel_name, - Map::cast(new_map), - array_type); + ElementsTransitionDescriptor desc(elements_transition_sentinel_name, + Map::cast(new_map), + elements_kind); Object* new_descriptors; MaybeObject* maybe_new_descriptors = descriptors->CopyInsert( &desc, @@ -2498,7 +2462,7 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); } case NULL_DESCRIPTOR: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); default: UNREACHABLE(); @@ -2586,7 +2550,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( // if the value is a function. return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); case NULL_DESCRIPTOR: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); default: UNREACHABLE(); @@ -2867,7 +2831,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, case CONSTANT_TRANSITION: case NULL_DESCRIPTOR: case INTERCEPTOR: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: break; default: UNREACHABLE(); @@ -6212,7 +6176,7 @@ void Map::CreateBackPointers() { DescriptorArray* descriptors = instance_descriptors(); for (int i = 0; i < descriptors->number_of_descriptors(); i++) { if (descriptors->GetType(i) == MAP_TRANSITION || - descriptors->GetType(i) == EXTERNAL_ARRAY_TRANSITION || + descriptors->GetType(i) == ELEMENTS_TRANSITION || descriptors->GetType(i) == CONSTANT_TRANSITION) { // Get target. Map* target = Map::cast(descriptors->GetValue(i)); @@ -6255,7 +6219,7 @@ void Map::ClearNonLiveTransitions(Heap* heap, Object* real_prototype) { // non-live object. PropertyDetails details(Smi::cast(contents->get(i + 1))); if (details.type() == MAP_TRANSITION || - details.type() == EXTERNAL_ARRAY_TRANSITION || + details.type() == ELEMENTS_TRANSITION || details.type() == CONSTANT_TRANSITION) { Map* target = reinterpret_cast(contents->get(i)); ASSERT(target->IsHeapObject()); @@ -7144,7 +7108,7 @@ const char* Code::PropertyType2String(PropertyType type) { case HANDLER: return "HANDLER"; case INTERCEPTOR: return "INTERCEPTOR"; case MAP_TRANSITION: return "MAP_TRANSITION"; - case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION"; + case ELEMENTS_TRANSITION: return "ELEMENTS_TRANSITION"; case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; } diff --git a/src/objects.h b/src/objects.h index ee0dff3..af7ce9c 100644 --- a/src/objects.h +++ b/src/objects.h @@ -174,7 +174,7 @@ class PropertyDetails BASE_EMBEDDED { PropertyDetails(PropertyAttributes attributes, PropertyType type, int index = 0) { - ASSERT(type != EXTERNAL_ARRAY_TRANSITION); + ASSERT(type != ELEMENTS_TRANSITION); ASSERT(TypeField::is_valid(type)); ASSERT(AttributesField::is_valid(attributes)); ASSERT(StorageField::is_valid(index)); @@ -190,19 +190,19 @@ class PropertyDetails BASE_EMBEDDED { PropertyDetails(PropertyAttributes attributes, PropertyType type, - ExternalArrayType array_type) { - ASSERT(type == EXTERNAL_ARRAY_TRANSITION); + ElementsKind elements_kind) { + ASSERT(type == ELEMENTS_TRANSITION); ASSERT(TypeField::is_valid(type)); ASSERT(AttributesField::is_valid(attributes)); - ASSERT(StorageField::is_valid(static_cast(array_type))); + ASSERT(StorageField::is_valid(static_cast(elements_kind))); value_ = TypeField::encode(type) | AttributesField::encode(attributes) - | StorageField::encode(static_cast(array_type)); + | StorageField::encode(static_cast(elements_kind)); ASSERT(type == this->type()); ASSERT(attributes == this->attributes()); - ASSERT(array_type == this->array_type()); + ASSERT(elements_kind == this->elements_kind()); } // Conversion for storing details as Object*. @@ -215,7 +215,7 @@ class PropertyDetails BASE_EMBEDDED { PropertyType t = type(); ASSERT(t != INTERCEPTOR); return t == MAP_TRANSITION || t == CONSTANT_TRANSITION || - t == EXTERNAL_ARRAY_TRANSITION; + t == ELEMENTS_TRANSITION; } bool IsProperty() { @@ -226,9 +226,9 @@ class PropertyDetails BASE_EMBEDDED { int index() { return StorageField::decode(value_); } - ExternalArrayType array_type() { - ASSERT(type() == EXTERNAL_ARRAY_TRANSITION); - return static_cast(StorageField::decode(value_)); + ElementsKind elements_kind() { + ASSERT(type() == ELEMENTS_TRANSITION); + return static_cast(StorageField::decode(value_)); } inline PropertyDetails AsDeleted(); @@ -4154,9 +4154,9 @@ class Map: public HeapObject { MUST_USE_RESULT inline MaybeObject* GetSlowElementsMap(); // Returns a new map with all transitions dropped from the descriptors and the - // ElementsKind set to one of the value corresponding to array_type. - MUST_USE_RESULT MaybeObject* GetExternalArrayElementsMap( - ExternalArrayType array_type, + // ElementsKind set. + MUST_USE_RESULT MaybeObject* GetElementsTransitionMap( + ElementsKind elements_kind, bool safe_to_add_transition); // Returns the property index for name (only valid for FAST MODE). diff --git a/src/property.cc b/src/property.cc index dd23209..7cc2df5 100644 --- a/src/property.cc +++ b/src/property.cc @@ -1,4 +1,4 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Copyright 2011 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: @@ -52,8 +52,8 @@ void LookupResult::Print(FILE* out) { GetTransitionMap()->Print(out); PrintF(out, "\n"); break; - case EXTERNAL_ARRAY_TRANSITION: - PrintF(out, " -type = external array transition\n"); + case ELEMENTS_TRANSITION: + PrintF(out, " -type = elements transition\n"); PrintF(out, " -map:\n"); GetTransitionMap()->Print(out); PrintF(out, "\n"); diff --git a/src/property.h b/src/property.h index ddecc92..e7d9fc5 100644 --- a/src/property.h +++ b/src/property.h @@ -1,4 +1,4 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Copyright 2011 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: @@ -112,14 +112,14 @@ class MapTransitionDescriptor: public Descriptor { : Descriptor(key, map, attributes, MAP_TRANSITION) { } }; -class ExternalArrayTransitionDescriptor: public Descriptor { +class ElementsTransitionDescriptor: public Descriptor { public: - ExternalArrayTransitionDescriptor(String* key, - Map* map, - ExternalArrayType array_type) + ElementsTransitionDescriptor(String* key, + Map* map, + ElementsKind elements_kind) : Descriptor(key, map, PropertyDetails(NONE, - EXTERNAL_ARRAY_TRANSITION, - array_type)) { } + ELEMENTS_TRANSITION, + elements_kind)) { } }; // Marks a field name in a map so that adding the field is guaranteed @@ -281,7 +281,7 @@ class LookupResult BASE_EMBEDDED { Map* GetTransitionMap() { ASSERT(lookup_type_ == DESCRIPTOR_TYPE); ASSERT(type() == MAP_TRANSITION || type() == CONSTANT_TRANSITION || - type() == EXTERNAL_ARRAY_TRANSITION); + type() == ELEMENTS_TRANSITION); return Map::cast(GetValue()); } diff --git a/src/runtime.cc b/src/runtime.cc index abc71b3..f7a764c 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -10145,7 +10145,7 @@ static MaybeObject* DebugLookupResultValue(Heap* heap, } case INTERCEPTOR: case MAP_TRANSITION: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: case CONSTANT_TRANSITION: case NULL_DESCRIPTOR: return heap->undefined_value(); diff --git a/src/v8globals.h b/src/v8globals.h index aff2757..8be5db1 100644 --- a/src/v8globals.h +++ b/src/v8globals.h @@ -334,7 +334,7 @@ enum PropertyType { HANDLER = 4, // only in lookup results, not in descriptors INTERCEPTOR = 5, // only in lookup results, not in descriptors MAP_TRANSITION = 6, // only in fast mode - EXTERNAL_ARRAY_TRANSITION = 7, + ELEMENTS_TRANSITION = 7, CONSTANT_TRANSITION = 8, // only in fast mode NULL_DESCRIPTOR = 9, // only in fast mode // All properties before MAP_TRANSITION are real.