| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 3215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3226 } | 3226 } |
| 3227 current_map = maybe_transitioned_map; | 3227 current_map = maybe_transitioned_map; |
| 3228 } | 3228 } |
| 3229 } | 3229 } |
| 3230 return transitioned_map; | 3230 return transitioned_map; |
| 3231 } | 3231 } |
| 3232 | 3232 |
| 3233 | 3233 |
| 3234 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 3234 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
| 3235 Map* current_map = map; | 3235 Map* current_map = map; |
| 3236 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); | 3236 int target_kind = |
| 3237 int to_index = IsFastElementsKind(to_kind) | 3237 IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind) |
| 3238 ? GetSequenceIndexFromFastElementsKind(to_kind) | 3238 ? to_kind |
| 3239 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); | 3239 : TERMINAL_FAST_ELEMENTS_KIND; |
| 3240 | 3240 |
| 3241 ASSERT(index <= to_index); | 3241 // Support for legacy API. |
| 3242 if (IsExternalArrayElementsKind(to_kind) && |
| 3243 !IsFixedTypedArrayElementsKind(map->elements_kind())) { |
| 3244 return map; |
| 3245 } |
| 3242 | 3246 |
| 3243 for (; index < to_index; ++index) { | 3247 ElementsKind kind = map->elements_kind(); |
| 3248 while (kind != target_kind) { |
| 3249 kind = GetNextTransitionElementsKind(kind); |
| 3244 if (!current_map->HasElementsTransition()) return current_map; | 3250 if (!current_map->HasElementsTransition()) return current_map; |
| 3245 current_map = current_map->elements_transition_map(); | 3251 current_map = current_map->elements_transition_map(); |
| 3246 } | 3252 } |
| 3247 if (!IsFastElementsKind(to_kind) && current_map->HasElementsTransition()) { | 3253 |
| 3254 if (to_kind != kind && current_map->HasElementsTransition()) { |
| 3255 ASSERT(to_kind == DICTIONARY_ELEMENTS); |
| 3248 Map* next_map = current_map->elements_transition_map(); | 3256 Map* next_map = current_map->elements_transition_map(); |
| 3249 if (next_map->elements_kind() == to_kind) return next_map; | 3257 if (next_map->elements_kind() == to_kind) return next_map; |
| 3250 } | 3258 } |
| 3251 ASSERT(IsFastElementsKind(to_kind) | 3259 |
| 3252 ? current_map->elements_kind() == to_kind | 3260 ASSERT(current_map->elements_kind() == target_kind); |
| 3253 : current_map->elements_kind() == TERMINAL_FAST_ELEMENTS_KIND); | |
| 3254 return current_map; | 3261 return current_map; |
| 3255 } | 3262 } |
| 3256 | 3263 |
| 3257 | 3264 |
| 3258 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { | 3265 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { |
| 3259 Map* to_map = FindClosestElementsTransition(this, to_kind); | 3266 Map* to_map = FindClosestElementsTransition(this, to_kind); |
| 3260 if (to_map->elements_kind() == to_kind) return to_map; | 3267 if (to_map->elements_kind() == to_kind) return to_map; |
| 3261 return NULL; | 3268 return NULL; |
| 3262 } | 3269 } |
| 3263 | 3270 |
| 3264 | 3271 |
| 3265 bool Map::IsMapInArrayPrototypeChain() { | 3272 bool Map::IsMapInArrayPrototypeChain() { |
| 3266 Isolate* isolate = GetIsolate(); | 3273 Isolate* isolate = GetIsolate(); |
| 3267 if (isolate->initial_array_prototype()->map() == this) { | 3274 if (isolate->initial_array_prototype()->map() == this) { |
| 3268 return true; | 3275 return true; |
| 3269 } | 3276 } |
| 3270 | 3277 |
| 3271 if (isolate->initial_object_prototype()->map() == this) { | 3278 if (isolate->initial_object_prototype()->map() == this) { |
| 3272 return true; | 3279 return true; |
| 3273 } | 3280 } |
| 3274 | 3281 |
| 3275 return false; | 3282 return false; |
| 3276 } | 3283 } |
| 3277 | 3284 |
| 3278 | 3285 |
| 3279 static MaybeObject* AddMissingElementsTransitions(Map* map, | 3286 static MaybeObject* AddMissingElementsTransitions(Map* map, |
| 3280 ElementsKind to_kind) { | 3287 ElementsKind to_kind) { |
| 3281 ASSERT(IsFastElementsKind(map->elements_kind())); | 3288 ASSERT(IsTransitionElementsKind(map->elements_kind())); |
| 3282 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); | |
| 3283 int to_index = IsFastElementsKind(to_kind) | |
| 3284 ? GetSequenceIndexFromFastElementsKind(to_kind) | |
| 3285 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); | |
| 3286 | |
| 3287 ASSERT(index <= to_index); | |
| 3288 | 3289 |
| 3289 Map* current_map = map; | 3290 Map* current_map = map; |
| 3290 | 3291 |
| 3291 for (; index < to_index; ++index) { | 3292 ElementsKind kind = map->elements_kind(); |
| 3292 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index + 1); | 3293 while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
| 3294 kind = GetNextTransitionElementsKind(kind); |
| 3293 MaybeObject* maybe_next_map = | 3295 MaybeObject* maybe_next_map = |
| 3294 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); | 3296 current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); |
| 3295 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3297 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
| 3296 } | 3298 } |
| 3297 | 3299 |
| 3298 // In case we are exiting the fast elements kind system, just add the map in | 3300 // In case we are exiting the fast elements kind system, just add the map in |
| 3299 // the end. | 3301 // the end. |
| 3300 if (!IsFastElementsKind(to_kind)) { | 3302 if (kind != to_kind) { |
| 3301 MaybeObject* maybe_next_map = | 3303 MaybeObject* maybe_next_map = |
| 3302 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); | 3304 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); |
| 3303 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3305 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
| 3304 } | 3306 } |
| 3305 | 3307 |
| 3306 ASSERT(current_map->elements_kind() == to_kind); | 3308 ASSERT(current_map->elements_kind() == to_kind); |
| 3307 return current_map; | 3309 return current_map; |
| 3308 } | 3310 } |
| 3309 | 3311 |
| 3310 | 3312 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3322 ElementsKind from_kind = start_map->elements_kind(); | 3324 ElementsKind from_kind = start_map->elements_kind(); |
| 3323 | 3325 |
| 3324 if (from_kind == to_kind) { | 3326 if (from_kind == to_kind) { |
| 3325 return start_map; | 3327 return start_map; |
| 3326 } | 3328 } |
| 3327 | 3329 |
| 3328 bool allow_store_transition = | 3330 bool allow_store_transition = |
| 3329 // Only remember the map transition if there is not an already existing | 3331 // Only remember the map transition if there is not an already existing |
| 3330 // non-matching element transition. | 3332 // non-matching element transition. |
| 3331 !start_map->IsUndefined() && !start_map->is_shared() && | 3333 !start_map->IsUndefined() && !start_map->is_shared() && |
| 3332 IsFastElementsKind(from_kind); | 3334 IsTransitionElementsKind(from_kind); |
| 3333 | 3335 |
| 3334 // Only store fast element maps in ascending generality. | 3336 // Only store fast element maps in ascending generality. |
| 3335 if (IsFastElementsKind(to_kind)) { | 3337 if (IsFastElementsKind(to_kind)) { |
| 3336 allow_store_transition &= | 3338 allow_store_transition &= |
| 3337 IsTransitionableFastElementsKind(from_kind) && | 3339 IsTransitionableFastElementsKind(from_kind) && |
| 3338 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 3340 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
| 3339 } | 3341 } |
| 3340 | 3342 |
| 3341 if (!allow_store_transition) { | 3343 if (!allow_store_transition) { |
| 3342 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); | 3344 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); |
| (...skipping 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4694 dictionary = | 4696 dictionary = |
| 4695 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); | 4697 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); |
| 4696 } | 4698 } |
| 4697 } | 4699 } |
| 4698 return dictionary; | 4700 return dictionary; |
| 4699 } | 4701 } |
| 4700 | 4702 |
| 4701 | 4703 |
| 4702 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4704 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
| 4703 Handle<JSObject> object) { | 4705 Handle<JSObject> object) { |
| 4704 ASSERT(!object->HasExternalArrayElements()); | 4706 ASSERT(!object->HasExternalArrayElements() && |
| 4707 !object->HasFixedTypedArrayElements()); |
| 4705 Isolate* isolate = object->GetIsolate(); | 4708 Isolate* isolate = object->GetIsolate(); |
| 4706 Factory* factory = isolate->factory(); | 4709 Factory* factory = isolate->factory(); |
| 4707 | 4710 |
| 4708 // Find the backing store. | 4711 // Find the backing store. |
| 4709 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); | 4712 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); |
| 4710 bool is_arguments = | 4713 bool is_arguments = |
| 4711 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); | 4714 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); |
| 4712 if (is_arguments) { | 4715 if (is_arguments) { |
| 4713 array = handle(FixedArrayBase::cast( | 4716 array = handle(FixedArrayBase::cast( |
| 4714 Handle<FixedArray>::cast(array)->get(1))); | 4717 Handle<FixedArray>::cast(array)->get(1))); |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5429 } | 5432 } |
| 5430 | 5433 |
| 5431 if (object->IsJSGlobalProxy()) { | 5434 if (object->IsJSGlobalProxy()) { |
| 5432 Handle<Object> proto(object->GetPrototype(), isolate); | 5435 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5433 if (proto->IsNull()) return object; | 5436 if (proto->IsNull()) return object; |
| 5434 ASSERT(proto->IsJSGlobalObject()); | 5437 ASSERT(proto->IsJSGlobalObject()); |
| 5435 return PreventExtensions(Handle<JSObject>::cast(proto)); | 5438 return PreventExtensions(Handle<JSObject>::cast(proto)); |
| 5436 } | 5439 } |
| 5437 | 5440 |
| 5438 // It's not possible to seal objects with external array elements | 5441 // It's not possible to seal objects with external array elements |
| 5439 if (object->HasExternalArrayElements()) { | 5442 if (object->HasExternalArrayElements() || |
| 5443 object->HasFixedTypedArrayElements()) { |
| 5440 Handle<Object> error = | 5444 Handle<Object> error = |
| 5441 isolate->factory()->NewTypeError( | 5445 isolate->factory()->NewTypeError( |
| 5442 "cant_prevent_ext_external_array_elements", | 5446 "cant_prevent_ext_external_array_elements", |
| 5443 HandleVector(&object, 1)); | 5447 HandleVector(&object, 1)); |
| 5444 isolate->Throw(*error); | 5448 isolate->Throw(*error); |
| 5445 return Handle<Object>(); | 5449 return Handle<Object>(); |
| 5446 } | 5450 } |
| 5447 | 5451 |
| 5448 // If there are fast elements we normalize. | 5452 // If there are fast elements we normalize. |
| 5449 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 5453 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5509 } | 5513 } |
| 5510 | 5514 |
| 5511 if (object->IsJSGlobalProxy()) { | 5515 if (object->IsJSGlobalProxy()) { |
| 5512 Handle<Object> proto(object->GetPrototype(), isolate); | 5516 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5513 if (proto->IsNull()) return object; | 5517 if (proto->IsNull()) return object; |
| 5514 ASSERT(proto->IsJSGlobalObject()); | 5518 ASSERT(proto->IsJSGlobalObject()); |
| 5515 return Freeze(Handle<JSObject>::cast(proto)); | 5519 return Freeze(Handle<JSObject>::cast(proto)); |
| 5516 } | 5520 } |
| 5517 | 5521 |
| 5518 // It's not possible to freeze objects with external array elements | 5522 // It's not possible to freeze objects with external array elements |
| 5519 if (object->HasExternalArrayElements()) { | 5523 if (object->HasExternalArrayElements() || |
| 5524 object->HasFixedTypedArrayElements()) { |
| 5520 Handle<Object> error = | 5525 Handle<Object> error = |
| 5521 isolate->factory()->NewTypeError( | 5526 isolate->factory()->NewTypeError( |
| 5522 "cant_prevent_ext_external_array_elements", | 5527 "cant_prevent_ext_external_array_elements", |
| 5523 HandleVector(&object, 1)); | 5528 HandleVector(&object, 1)); |
| 5524 isolate->Throw(*error); | 5529 isolate->Throw(*error); |
| 5525 return Handle<Object>(); | 5530 return Handle<Object>(); |
| 5526 } | 5531 } |
| 5527 | 5532 |
| 5528 Handle<SeededNumberDictionary> new_element_dictionary; | 5533 Handle<SeededNumberDictionary> new_element_dictionary; |
| 5529 if (!object->elements()->IsDictionary()) { | 5534 if (!object->elements()->IsDictionary()) { |
| (...skipping 6898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12428 Handle<Object> proto(object->GetPrototype(), isolate); | 12433 Handle<Object> proto(object->GetPrototype(), isolate); |
| 12429 if (proto->IsNull()) return value; | 12434 if (proto->IsNull()) return value; |
| 12430 ASSERT(proto->IsJSGlobalObject()); | 12435 ASSERT(proto->IsJSGlobalObject()); |
| 12431 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, | 12436 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
| 12432 strict_mode, | 12437 strict_mode, |
| 12433 check_prototype, | 12438 check_prototype, |
| 12434 set_mode); | 12439 set_mode); |
| 12435 } | 12440 } |
| 12436 | 12441 |
| 12437 // Don't allow element properties to be redefined for external arrays. | 12442 // Don't allow element properties to be redefined for external arrays. |
| 12438 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 12443 if ((object->HasExternalArrayElements() || |
| 12444 object->HasFixedTypedArrayElements()) && |
| 12445 set_mode == DEFINE_PROPERTY) { |
| 12439 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12446 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12440 Handle<Object> args[] = { object, number }; | 12447 Handle<Object> args[] = { object, number }; |
| 12441 Handle<Object> error = isolate->factory()->NewTypeError( | 12448 Handle<Object> error = isolate->factory()->NewTypeError( |
| 12442 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12449 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
| 12443 isolate->Throw(*error); | 12450 isolate->Throw(*error); |
| 12444 return Handle<Object>(); | 12451 return Handle<Object>(); |
| 12445 } | 12452 } |
| 12446 | 12453 |
| 12447 // Normalize the elements to enable attributes on the property. | 12454 // Normalize the elements to enable attributes on the property. |
| 12448 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12455 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
| (...skipping 1898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14347 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); | 14354 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); |
| 14348 | 14355 |
| 14349 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? | 14356 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? |
| 14350 NOT_TENURED: TENURED; | 14357 NOT_TENURED: TENURED; |
| 14351 Handle<FixedArray> fast_elements = | 14358 Handle<FixedArray> fast_elements = |
| 14352 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14359 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
| 14353 dict->CopyValuesTo(*fast_elements); | 14360 dict->CopyValuesTo(*fast_elements); |
| 14354 object->ValidateElements(); | 14361 object->ValidateElements(); |
| 14355 | 14362 |
| 14356 object->set_map_and_elements(*new_map, *fast_elements); | 14363 object->set_map_and_elements(*new_map, *fast_elements); |
| 14357 } else if (object->HasExternalArrayElements()) { | 14364 } else if (object->HasExternalArrayElements() || |
| 14358 // External arrays cannot have holes or undefined elements. | 14365 object->HasFixedTypedArrayElements()) { |
| 14366 // Typed arrays cannot have holes or undefined elements. |
| 14359 return handle(Smi::FromInt( | 14367 return handle(Smi::FromInt( |
| 14360 ExternalArray::cast(object->elements())->length()), isolate); | 14368 FixedArrayBase::cast(object->elements())->length()), isolate); |
| 14361 } else if (!object->HasFastDoubleElements()) { | 14369 } else if (!object->HasFastDoubleElements()) { |
| 14362 EnsureWritableFastElements(object); | 14370 EnsureWritableFastElements(object); |
| 14363 } | 14371 } |
| 14364 ASSERT(object->HasFastSmiOrObjectElements() || | 14372 ASSERT(object->HasFastSmiOrObjectElements() || |
| 14365 object->HasFastDoubleElements()); | 14373 object->HasFastDoubleElements()); |
| 14366 | 14374 |
| 14367 // Collect holes at the end, undefined before that and the rest at the | 14375 // Collect holes at the end, undefined before that and the rest at the |
| 14368 // start, and return the number of non-hole, non-undefined values. | 14376 // start, and return the number of non-hole, non-undefined values. |
| 14369 | 14377 |
| 14370 Handle<FixedArrayBase> elements_base(object->elements()); | 14378 Handle<FixedArrayBase> elements_base(object->elements()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14451 } | 14459 } |
| 14452 | 14460 |
| 14453 return isolate->factory()->NewNumberFromUint(result); | 14461 return isolate->factory()->NewNumberFromUint(result); |
| 14454 } | 14462 } |
| 14455 | 14463 |
| 14456 | 14464 |
| 14457 ExternalArrayType JSTypedArray::type() { | 14465 ExternalArrayType JSTypedArray::type() { |
| 14458 switch (elements()->map()->instance_type()) { | 14466 switch (elements()->map()->instance_type()) { |
| 14459 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ | 14467 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ |
| 14460 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14468 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
| 14469 case FIXED_##TYPE##_ARRAY_TYPE: \ |
| 14461 return kExternal##Type##Array; | 14470 return kExternal##Type##Array; |
| 14462 | 14471 |
| 14463 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) | 14472 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) |
| 14464 #undef INSTANCE_TYPE_TO_ARRAY_TYPE | 14473 #undef INSTANCE_TYPE_TO_ARRAY_TYPE |
| 14465 | 14474 |
| 14466 default: | 14475 default: |
| 14476 UNREACHABLE(); |
| 14467 return static_cast<ExternalArrayType>(-1); | 14477 return static_cast<ExternalArrayType>(-1); |
| 14468 } | 14478 } |
| 14469 } | 14479 } |
| 14470 | 14480 |
| 14471 | 14481 |
| 14472 size_t JSTypedArray::element_size() { | 14482 size_t JSTypedArray::element_size() { |
| 14473 switch (elements()->map()->instance_type()) { | 14483 switch (elements()->map()->instance_type()) { |
| 14474 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ | 14484 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ |
| 14475 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14485 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
| 14476 return size; | 14486 return size; |
| (...skipping 1818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16295 } | 16305 } |
| 16296 | 16306 |
| 16297 | 16307 |
| 16298 void JSTypedArray::Neuter() { | 16308 void JSTypedArray::Neuter() { |
| 16299 NeuterView(); | 16309 NeuterView(); |
| 16300 set_length(Smi::FromInt(0)); | 16310 set_length(Smi::FromInt(0)); |
| 16301 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); | 16311 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); |
| 16302 } | 16312 } |
| 16303 | 16313 |
| 16304 | 16314 |
| 16315 static ElementsKind FixedToExternalElementsKind(ElementsKind elements_kind) { |
| 16316 switch (elements_kind) { |
| 16317 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 16318 case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS; |
| 16319 |
| 16320 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 16321 #undef TYPED_ARRAY_CASE |
| 16322 |
| 16323 default: |
| 16324 UNREACHABLE(); |
| 16325 return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND; |
| 16326 } |
| 16327 } |
| 16328 |
| 16329 |
| 16330 Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer( |
| 16331 Handle<JSTypedArray> typed_array) { |
| 16332 |
| 16333 Handle<Map> map(typed_array->map()); |
| 16334 Isolate* isolate = typed_array->GetIsolate(); |
| 16335 |
| 16336 ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind())); |
| 16337 |
| 16338 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
| 16339 Handle<FixedTypedArrayBase> fixed_typed_array( |
| 16340 FixedTypedArrayBase::cast(typed_array->elements())); |
| 16341 Runtime::SetupArrayBufferAllocatingData(isolate, buffer, |
| 16342 fixed_typed_array->DataSize(), false); |
| 16343 memcpy(buffer->backing_store(), |
| 16344 fixed_typed_array->DataPtr(), |
| 16345 fixed_typed_array->DataSize()); |
| 16346 Handle<ExternalArray> new_elements = |
| 16347 isolate->factory()->NewExternalArray( |
| 16348 fixed_typed_array->length(), typed_array->type(), |
| 16349 static_cast<uint8_t*>(buffer->backing_store())); |
| 16350 Handle<Map> new_map = JSObject::GetElementsTransitionMap( |
| 16351 typed_array, |
| 16352 FixedToExternalElementsKind(map->elements_kind())); |
| 16353 |
| 16354 buffer->set_weak_first_view(*typed_array); |
| 16355 ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value()); |
| 16356 typed_array->set_buffer(*buffer); |
| 16357 typed_array->set_map_and_elements(*new_map, *new_elements); |
| 16358 |
| 16359 return buffer; |
| 16360 } |
| 16361 |
| 16362 |
| 16363 Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { |
| 16364 Handle<Object> result(buffer(), GetIsolate()); |
| 16365 if (*result != Smi::FromInt(0)) { |
| 16366 ASSERT(IsExternalArrayElementsKind(map()->elements_kind())); |
| 16367 return Handle<JSArrayBuffer>::cast(result); |
| 16368 } |
| 16369 Handle<JSTypedArray> self(this); |
| 16370 return MaterializeArrayBuffer(self); |
| 16371 } |
| 16372 |
| 16373 |
| 16305 HeapType* PropertyCell::type() { | 16374 HeapType* PropertyCell::type() { |
| 16306 return static_cast<HeapType*>(type_raw()); | 16375 return static_cast<HeapType*>(type_raw()); |
| 16307 } | 16376 } |
| 16308 | 16377 |
| 16309 | 16378 |
| 16310 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { | 16379 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { |
| 16311 ASSERT(IsPropertyCell()); | 16380 ASSERT(IsPropertyCell()); |
| 16312 set_type_raw(type, ignored); | 16381 set_type_raw(type, ignored); |
| 16313 } | 16382 } |
| 16314 | 16383 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16363 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16432 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16364 static const char* error_messages_[] = { | 16433 static const char* error_messages_[] = { |
| 16365 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16434 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16366 }; | 16435 }; |
| 16367 #undef ERROR_MESSAGES_TEXTS | 16436 #undef ERROR_MESSAGES_TEXTS |
| 16368 return error_messages_[reason]; | 16437 return error_messages_[reason]; |
| 16369 } | 16438 } |
| 16370 | 16439 |
| 16371 | 16440 |
| 16372 } } // namespace v8::internal | 16441 } } // namespace v8::internal |
| OLD | NEW |