| 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 3207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3218 } | 3218 } |
| 3219 current_map = maybe_transitioned_map; | 3219 current_map = maybe_transitioned_map; |
| 3220 } | 3220 } |
| 3221 } | 3221 } |
| 3222 return transitioned_map; | 3222 return transitioned_map; |
| 3223 } | 3223 } |
| 3224 | 3224 |
| 3225 | 3225 |
| 3226 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 3226 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
| 3227 Map* current_map = map; | 3227 Map* current_map = map; |
| 3228 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); | 3228 int target_kind = |
| 3229 int to_index = IsFastElementsKind(to_kind) | 3229 IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind) |
| 3230 ? GetSequenceIndexFromFastElementsKind(to_kind) | 3230 ? to_kind |
| 3231 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); | 3231 : TERMINAL_FAST_ELEMENTS_KIND; |
| 3232 | 3232 |
| 3233 ASSERT(index <= to_index); | 3233 // Support for legacy API. |
| 3234 if (IsExternalArrayElementsKind(to_kind) && |
| 3235 !IsFixedTypedArrayElementsKind(map->elements_kind())) { |
| 3236 return map; |
| 3237 } |
| 3234 | 3238 |
| 3235 for (; index < to_index; ++index) { | 3239 ElementsKind kind = map->elements_kind(); |
| 3240 while (kind != target_kind) { |
| 3241 kind = GetNextTransitionElementsKind(kind); |
| 3236 if (!current_map->HasElementsTransition()) return current_map; | 3242 if (!current_map->HasElementsTransition()) return current_map; |
| 3237 current_map = current_map->elements_transition_map(); | 3243 current_map = current_map->elements_transition_map(); |
| 3238 } | 3244 } |
| 3239 if (!IsFastElementsKind(to_kind) && current_map->HasElementsTransition()) { | 3245 |
| 3246 if (to_kind != kind && current_map->HasElementsTransition()) { |
| 3247 ASSERT(to_kind == DICTIONARY_ELEMENTS); |
| 3240 Map* next_map = current_map->elements_transition_map(); | 3248 Map* next_map = current_map->elements_transition_map(); |
| 3241 if (next_map->elements_kind() == to_kind) return next_map; | 3249 if (next_map->elements_kind() == to_kind) return next_map; |
| 3242 } | 3250 } |
| 3243 ASSERT(IsFastElementsKind(to_kind) | 3251 |
| 3244 ? current_map->elements_kind() == to_kind | 3252 ASSERT(current_map->elements_kind() == target_kind); |
| 3245 : current_map->elements_kind() == TERMINAL_FAST_ELEMENTS_KIND); | |
| 3246 return current_map; | 3253 return current_map; |
| 3247 } | 3254 } |
| 3248 | 3255 |
| 3249 | 3256 |
| 3250 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { | 3257 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { |
| 3251 Map* to_map = FindClosestElementsTransition(this, to_kind); | 3258 Map* to_map = FindClosestElementsTransition(this, to_kind); |
| 3252 if (to_map->elements_kind() == to_kind) return to_map; | 3259 if (to_map->elements_kind() == to_kind) return to_map; |
| 3253 return NULL; | 3260 return NULL; |
| 3254 } | 3261 } |
| 3255 | 3262 |
| 3256 | 3263 |
| 3257 bool Map::IsMapInArrayPrototypeChain() { | 3264 bool Map::IsMapInArrayPrototypeChain() { |
| 3258 Isolate* isolate = GetIsolate(); | 3265 Isolate* isolate = GetIsolate(); |
| 3259 if (isolate->initial_array_prototype()->map() == this) { | 3266 if (isolate->initial_array_prototype()->map() == this) { |
| 3260 return true; | 3267 return true; |
| 3261 } | 3268 } |
| 3262 | 3269 |
| 3263 if (isolate->initial_object_prototype()->map() == this) { | 3270 if (isolate->initial_object_prototype()->map() == this) { |
| 3264 return true; | 3271 return true; |
| 3265 } | 3272 } |
| 3266 | 3273 |
| 3267 return false; | 3274 return false; |
| 3268 } | 3275 } |
| 3269 | 3276 |
| 3270 | 3277 |
| 3271 static MaybeObject* AddMissingElementsTransitions(Map* map, | 3278 static MaybeObject* AddMissingElementsTransitions(Map* map, |
| 3272 ElementsKind to_kind) { | 3279 ElementsKind to_kind) { |
| 3273 ASSERT(IsFastElementsKind(map->elements_kind())); | 3280 ASSERT(IsTransitionElementsKind(map->elements_kind())); |
| 3274 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); | |
| 3275 int to_index = IsFastElementsKind(to_kind) | |
| 3276 ? GetSequenceIndexFromFastElementsKind(to_kind) | |
| 3277 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); | |
| 3278 | |
| 3279 ASSERT(index <= to_index); | |
| 3280 | 3281 |
| 3281 Map* current_map = map; | 3282 Map* current_map = map; |
| 3282 | 3283 |
| 3283 for (; index < to_index; ++index) { | 3284 ElementsKind kind = map->elements_kind(); |
| 3284 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index + 1); | 3285 while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
| 3286 kind = GetNextTransitionElementsKind(kind); |
| 3285 MaybeObject* maybe_next_map = | 3287 MaybeObject* maybe_next_map = |
| 3286 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); | 3288 current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); |
| 3287 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3289 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
| 3288 } | 3290 } |
| 3289 | 3291 |
| 3290 // In case we are exiting the fast elements kind system, just add the map in | 3292 // In case we are exiting the fast elements kind system, just add the map in |
| 3291 // the end. | 3293 // the end. |
| 3292 if (!IsFastElementsKind(to_kind)) { | 3294 if (kind != to_kind) { |
| 3293 MaybeObject* maybe_next_map = | 3295 MaybeObject* maybe_next_map = |
| 3294 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); | 3296 current_map->CopyAsElementsKind(to_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 ASSERT(current_map->elements_kind() == to_kind); | 3300 ASSERT(current_map->elements_kind() == to_kind); |
| 3299 return current_map; | 3301 return current_map; |
| 3300 } | 3302 } |
| 3301 | 3303 |
| 3302 | 3304 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3314 ElementsKind from_kind = start_map->elements_kind(); | 3316 ElementsKind from_kind = start_map->elements_kind(); |
| 3315 | 3317 |
| 3316 if (from_kind == to_kind) { | 3318 if (from_kind == to_kind) { |
| 3317 return start_map; | 3319 return start_map; |
| 3318 } | 3320 } |
| 3319 | 3321 |
| 3320 bool allow_store_transition = | 3322 bool allow_store_transition = |
| 3321 // Only remember the map transition if there is not an already existing | 3323 // Only remember the map transition if there is not an already existing |
| 3322 // non-matching element transition. | 3324 // non-matching element transition. |
| 3323 !start_map->IsUndefined() && !start_map->is_shared() && | 3325 !start_map->IsUndefined() && !start_map->is_shared() && |
| 3324 IsFastElementsKind(from_kind); | 3326 IsTransitionElementsKind(from_kind); |
| 3325 | 3327 |
| 3326 // Only store fast element maps in ascending generality. | 3328 // Only store fast element maps in ascending generality. |
| 3327 if (IsFastElementsKind(to_kind)) { | 3329 if (IsFastElementsKind(to_kind)) { |
| 3328 allow_store_transition &= | 3330 allow_store_transition &= |
| 3329 IsTransitionableFastElementsKind(from_kind) && | 3331 IsTransitionableFastElementsKind(from_kind) && |
| 3330 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 3332 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
| 3331 } | 3333 } |
| 3332 | 3334 |
| 3333 if (!allow_store_transition) { | 3335 if (!allow_store_transition) { |
| 3334 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); | 3336 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); |
| (...skipping 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4686 dictionary = | 4688 dictionary = |
| 4687 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); | 4689 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); |
| 4688 } | 4690 } |
| 4689 } | 4691 } |
| 4690 return dictionary; | 4692 return dictionary; |
| 4691 } | 4693 } |
| 4692 | 4694 |
| 4693 | 4695 |
| 4694 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4696 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
| 4695 Handle<JSObject> object) { | 4697 Handle<JSObject> object) { |
| 4696 ASSERT(!object->HasExternalArrayElements()); | 4698 ASSERT(!object->HasExternalArrayElements() && |
| 4699 !object->HasFixedTypedArrayElements()); |
| 4697 Isolate* isolate = object->GetIsolate(); | 4700 Isolate* isolate = object->GetIsolate(); |
| 4698 Factory* factory = isolate->factory(); | 4701 Factory* factory = isolate->factory(); |
| 4699 | 4702 |
| 4700 // Find the backing store. | 4703 // Find the backing store. |
| 4701 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); | 4704 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); |
| 4702 bool is_arguments = | 4705 bool is_arguments = |
| 4703 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); | 4706 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); |
| 4704 if (is_arguments) { | 4707 if (is_arguments) { |
| 4705 array = handle(FixedArrayBase::cast( | 4708 array = handle(FixedArrayBase::cast( |
| 4706 Handle<FixedArray>::cast(array)->get(1))); | 4709 Handle<FixedArray>::cast(array)->get(1))); |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5421 } | 5424 } |
| 5422 | 5425 |
| 5423 if (object->IsJSGlobalProxy()) { | 5426 if (object->IsJSGlobalProxy()) { |
| 5424 Handle<Object> proto(object->GetPrototype(), isolate); | 5427 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5425 if (proto->IsNull()) return object; | 5428 if (proto->IsNull()) return object; |
| 5426 ASSERT(proto->IsJSGlobalObject()); | 5429 ASSERT(proto->IsJSGlobalObject()); |
| 5427 return PreventExtensions(Handle<JSObject>::cast(proto)); | 5430 return PreventExtensions(Handle<JSObject>::cast(proto)); |
| 5428 } | 5431 } |
| 5429 | 5432 |
| 5430 // It's not possible to seal objects with external array elements | 5433 // It's not possible to seal objects with external array elements |
| 5431 if (object->HasExternalArrayElements()) { | 5434 if (object->HasExternalArrayElements() || |
| 5435 object->HasFixedTypedArrayElements()) { |
| 5432 Handle<Object> error = | 5436 Handle<Object> error = |
| 5433 isolate->factory()->NewTypeError( | 5437 isolate->factory()->NewTypeError( |
| 5434 "cant_prevent_ext_external_array_elements", | 5438 "cant_prevent_ext_external_array_elements", |
| 5435 HandleVector(&object, 1)); | 5439 HandleVector(&object, 1)); |
| 5436 isolate->Throw(*error); | 5440 isolate->Throw(*error); |
| 5437 return Handle<Object>(); | 5441 return Handle<Object>(); |
| 5438 } | 5442 } |
| 5439 | 5443 |
| 5440 // If there are fast elements we normalize. | 5444 // If there are fast elements we normalize. |
| 5441 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 5445 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5501 } | 5505 } |
| 5502 | 5506 |
| 5503 if (object->IsJSGlobalProxy()) { | 5507 if (object->IsJSGlobalProxy()) { |
| 5504 Handle<Object> proto(object->GetPrototype(), isolate); | 5508 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5505 if (proto->IsNull()) return object; | 5509 if (proto->IsNull()) return object; |
| 5506 ASSERT(proto->IsJSGlobalObject()); | 5510 ASSERT(proto->IsJSGlobalObject()); |
| 5507 return Freeze(Handle<JSObject>::cast(proto)); | 5511 return Freeze(Handle<JSObject>::cast(proto)); |
| 5508 } | 5512 } |
| 5509 | 5513 |
| 5510 // It's not possible to freeze objects with external array elements | 5514 // It's not possible to freeze objects with external array elements |
| 5511 if (object->HasExternalArrayElements()) { | 5515 if (object->HasExternalArrayElements() || |
| 5516 object->HasFixedTypedArrayElements()) { |
| 5512 Handle<Object> error = | 5517 Handle<Object> error = |
| 5513 isolate->factory()->NewTypeError( | 5518 isolate->factory()->NewTypeError( |
| 5514 "cant_prevent_ext_external_array_elements", | 5519 "cant_prevent_ext_external_array_elements", |
| 5515 HandleVector(&object, 1)); | 5520 HandleVector(&object, 1)); |
| 5516 isolate->Throw(*error); | 5521 isolate->Throw(*error); |
| 5517 return Handle<Object>(); | 5522 return Handle<Object>(); |
| 5518 } | 5523 } |
| 5519 | 5524 |
| 5520 Handle<SeededNumberDictionary> new_element_dictionary; | 5525 Handle<SeededNumberDictionary> new_element_dictionary; |
| 5521 if (!object->elements()->IsDictionary()) { | 5526 if (!object->elements()->IsDictionary()) { |
| (...skipping 6957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12479 Handle<Object> proto(object->GetPrototype(), isolate); | 12484 Handle<Object> proto(object->GetPrototype(), isolate); |
| 12480 if (proto->IsNull()) return value; | 12485 if (proto->IsNull()) return value; |
| 12481 ASSERT(proto->IsJSGlobalObject()); | 12486 ASSERT(proto->IsJSGlobalObject()); |
| 12482 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, | 12487 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
| 12483 strict_mode, | 12488 strict_mode, |
| 12484 check_prototype, | 12489 check_prototype, |
| 12485 set_mode); | 12490 set_mode); |
| 12486 } | 12491 } |
| 12487 | 12492 |
| 12488 // Don't allow element properties to be redefined for external arrays. | 12493 // Don't allow element properties to be redefined for external arrays. |
| 12489 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 12494 if ((object->HasExternalArrayElements() || |
| 12495 object->HasFixedTypedArrayElements()) && |
| 12496 set_mode == DEFINE_PROPERTY) { |
| 12490 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12497 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12491 Handle<Object> args[] = { object, number }; | 12498 Handle<Object> args[] = { object, number }; |
| 12492 Handle<Object> error = isolate->factory()->NewTypeError( | 12499 Handle<Object> error = isolate->factory()->NewTypeError( |
| 12493 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12500 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
| 12494 isolate->Throw(*error); | 12501 isolate->Throw(*error); |
| 12495 return Handle<Object>(); | 12502 return Handle<Object>(); |
| 12496 } | 12503 } |
| 12497 | 12504 |
| 12498 // Normalize the elements to enable attributes on the property. | 12505 // Normalize the elements to enable attributes on the property. |
| 12499 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12506 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
| (...skipping 1918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14418 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); | 14425 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); |
| 14419 | 14426 |
| 14420 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? | 14427 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? |
| 14421 NOT_TENURED: TENURED; | 14428 NOT_TENURED: TENURED; |
| 14422 Handle<FixedArray> fast_elements = | 14429 Handle<FixedArray> fast_elements = |
| 14423 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14430 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
| 14424 dict->CopyValuesTo(*fast_elements); | 14431 dict->CopyValuesTo(*fast_elements); |
| 14425 object->ValidateElements(); | 14432 object->ValidateElements(); |
| 14426 | 14433 |
| 14427 object->set_map_and_elements(*new_map, *fast_elements); | 14434 object->set_map_and_elements(*new_map, *fast_elements); |
| 14428 } else if (object->HasExternalArrayElements()) { | 14435 } else if (object->HasExternalArrayElements() || |
| 14429 // External arrays cannot have holes or undefined elements. | 14436 object->HasFixedTypedArrayElements()) { |
| 14437 // Typed arrays cannot have holes or undefined elements. |
| 14430 return handle(Smi::FromInt( | 14438 return handle(Smi::FromInt( |
| 14431 ExternalArray::cast(object->elements())->length()), isolate); | 14439 FixedArrayBase::cast(object->elements())->length()), isolate); |
| 14432 } else if (!object->HasFastDoubleElements()) { | 14440 } else if (!object->HasFastDoubleElements()) { |
| 14433 EnsureWritableFastElements(object); | 14441 EnsureWritableFastElements(object); |
| 14434 } | 14442 } |
| 14435 ASSERT(object->HasFastSmiOrObjectElements() || | 14443 ASSERT(object->HasFastSmiOrObjectElements() || |
| 14436 object->HasFastDoubleElements()); | 14444 object->HasFastDoubleElements()); |
| 14437 | 14445 |
| 14438 // Collect holes at the end, undefined before that and the rest at the | 14446 // Collect holes at the end, undefined before that and the rest at the |
| 14439 // start, and return the number of non-hole, non-undefined values. | 14447 // start, and return the number of non-hole, non-undefined values. |
| 14440 | 14448 |
| 14441 Handle<FixedArrayBase> elements_base(object->elements()); | 14449 Handle<FixedArrayBase> elements_base(object->elements()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14522 } | 14530 } |
| 14523 | 14531 |
| 14524 return isolate->factory()->NewNumberFromUint(result); | 14532 return isolate->factory()->NewNumberFromUint(result); |
| 14525 } | 14533 } |
| 14526 | 14534 |
| 14527 | 14535 |
| 14528 ExternalArrayType JSTypedArray::type() { | 14536 ExternalArrayType JSTypedArray::type() { |
| 14529 switch (elements()->map()->instance_type()) { | 14537 switch (elements()->map()->instance_type()) { |
| 14530 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ | 14538 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ |
| 14531 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14539 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
| 14540 case FIXED_##TYPE##_ARRAY_TYPE: \ |
| 14532 return kExternal##Type##Array; | 14541 return kExternal##Type##Array; |
| 14533 | 14542 |
| 14534 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) | 14543 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) |
| 14535 #undef INSTANCE_TYPE_TO_ARRAY_TYPE | 14544 #undef INSTANCE_TYPE_TO_ARRAY_TYPE |
| 14536 | 14545 |
| 14537 default: | 14546 default: |
| 14547 UNREACHABLE(); |
| 14538 return static_cast<ExternalArrayType>(-1); | 14548 return static_cast<ExternalArrayType>(-1); |
| 14539 } | 14549 } |
| 14540 } | 14550 } |
| 14541 | 14551 |
| 14542 | 14552 |
| 14543 size_t JSTypedArray::element_size() { | 14553 size_t JSTypedArray::element_size() { |
| 14544 switch (elements()->map()->instance_type()) { | 14554 switch (elements()->map()->instance_type()) { |
| 14545 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ | 14555 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ |
| 14546 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14556 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
| 14547 return size; | 14557 return size; |
| (...skipping 1818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16366 } | 16376 } |
| 16367 | 16377 |
| 16368 | 16378 |
| 16369 void JSTypedArray::Neuter() { | 16379 void JSTypedArray::Neuter() { |
| 16370 NeuterView(); | 16380 NeuterView(); |
| 16371 set_length(Smi::FromInt(0)); | 16381 set_length(Smi::FromInt(0)); |
| 16372 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); | 16382 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); |
| 16373 } | 16383 } |
| 16374 | 16384 |
| 16375 | 16385 |
| 16386 static ElementsKind FixedToExternalElementsKind(ElementsKind elements_kind) { |
| 16387 switch (elements_kind) { |
| 16388 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 16389 case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS; |
| 16390 |
| 16391 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 16392 #undef TYPED_ARRAY_CASE |
| 16393 |
| 16394 default: |
| 16395 UNREACHABLE(); |
| 16396 return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND; |
| 16397 } |
| 16398 } |
| 16399 |
| 16400 |
| 16401 Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer( |
| 16402 Handle<JSTypedArray> typed_array) { |
| 16403 |
| 16404 Handle<Map> map(typed_array->map()); |
| 16405 Isolate* isolate = typed_array->GetIsolate(); |
| 16406 |
| 16407 ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind())); |
| 16408 |
| 16409 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
| 16410 Handle<FixedTypedArrayBase> fixed_typed_array( |
| 16411 FixedTypedArrayBase::cast(typed_array->elements())); |
| 16412 Runtime::SetupArrayBufferAllocatingData(isolate, buffer, |
| 16413 fixed_typed_array->DataSize(), false); |
| 16414 memcpy(buffer->backing_store(), |
| 16415 fixed_typed_array->DataPtr(), |
| 16416 fixed_typed_array->DataSize()); |
| 16417 Handle<ExternalArray> new_elements = |
| 16418 isolate->factory()->NewExternalArray( |
| 16419 fixed_typed_array->length(), typed_array->type(), |
| 16420 static_cast<uint8_t*>(buffer->backing_store())); |
| 16421 Handle<Map> new_map = |
| 16422 isolate->factory()->GetElementsTransitionMap( |
| 16423 typed_array, |
| 16424 FixedToExternalElementsKind(map->elements_kind())); |
| 16425 |
| 16426 buffer->set_weak_first_view(*typed_array); |
| 16427 ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value()); |
| 16428 typed_array->set_buffer(*buffer); |
| 16429 typed_array->set_map_and_elements(*new_map, *new_elements); |
| 16430 |
| 16431 return buffer; |
| 16432 } |
| 16433 |
| 16434 |
| 16435 Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { |
| 16436 Handle<Object> result(buffer(), GetIsolate()); |
| 16437 if (*result != Smi::FromInt(0)) { |
| 16438 ASSERT(IsExternalArrayElementsKind(map()->elements_kind())); |
| 16439 return Handle<JSArrayBuffer>::cast(result); |
| 16440 } |
| 16441 Handle<JSTypedArray> self(this); |
| 16442 return MaterializeArrayBuffer(self); |
| 16443 } |
| 16444 |
| 16445 |
| 16376 HeapType* PropertyCell::type() { | 16446 HeapType* PropertyCell::type() { |
| 16377 return static_cast<HeapType*>(type_raw()); | 16447 return static_cast<HeapType*>(type_raw()); |
| 16378 } | 16448 } |
| 16379 | 16449 |
| 16380 | 16450 |
| 16381 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { | 16451 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { |
| 16382 ASSERT(IsPropertyCell()); | 16452 ASSERT(IsPropertyCell()); |
| 16383 set_type_raw(type, ignored); | 16453 set_type_raw(type, ignored); |
| 16384 } | 16454 } |
| 16385 | 16455 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16434 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16504 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16435 static const char* error_messages_[] = { | 16505 static const char* error_messages_[] = { |
| 16436 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16506 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16437 }; | 16507 }; |
| 16438 #undef ERROR_MESSAGES_TEXTS | 16508 #undef ERROR_MESSAGES_TEXTS |
| 16439 return error_messages_[reason]; | 16509 return error_messages_[reason]; |
| 16440 } | 16510 } |
| 16441 | 16511 |
| 16442 | 16512 |
| 16443 } } // namespace v8::internal | 16513 } } // namespace v8::internal |
| OLD | NEW |