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 3214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3225 } | 3225 } |
3226 current_map = maybe_transitioned_map; | 3226 current_map = maybe_transitioned_map; |
3227 } | 3227 } |
3228 } | 3228 } |
3229 return transitioned_map; | 3229 return transitioned_map; |
3230 } | 3230 } |
3231 | 3231 |
3232 | 3232 |
3233 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 3233 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
3234 Map* current_map = map; | 3234 Map* current_map = map; |
3235 int target_kind = | 3235 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); |
3236 IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind) | 3236 int to_index = IsFastElementsKind(to_kind) |
3237 ? to_kind | 3237 ? GetSequenceIndexFromFastElementsKind(to_kind) |
3238 : TERMINAL_FAST_ELEMENTS_KIND; | 3238 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); |
3239 | 3239 |
3240 // Support for legacy API. | 3240 ASSERT(index <= to_index); |
3241 if (IsExternalArrayElementsKind(to_kind) && | |
3242 !IsFixedTypedArrayElementsKind(map->elements_kind())) { | |
3243 return map; | |
3244 } | |
3245 | 3241 |
3246 ElementsKind kind = map->elements_kind(); | 3242 for (; index < to_index; ++index) { |
3247 while (kind != target_kind) { | |
3248 kind = GetNextTransitionElementsKind(kind); | |
3249 if (!current_map->HasElementsTransition()) return current_map; | 3243 if (!current_map->HasElementsTransition()) return current_map; |
3250 current_map = current_map->elements_transition_map(); | 3244 current_map = current_map->elements_transition_map(); |
3251 } | 3245 } |
3252 | 3246 if (!IsFastElementsKind(to_kind) && current_map->HasElementsTransition()) { |
3253 if (to_kind != kind && current_map->HasElementsTransition()) { | |
3254 ASSERT(to_kind == DICTIONARY_ELEMENTS); | |
3255 Map* next_map = current_map->elements_transition_map(); | 3247 Map* next_map = current_map->elements_transition_map(); |
3256 if (next_map->elements_kind() == to_kind) return next_map; | 3248 if (next_map->elements_kind() == to_kind) return next_map; |
3257 } | 3249 } |
3258 | 3250 ASSERT(IsFastElementsKind(to_kind) |
3259 ASSERT(current_map->elements_kind() == target_kind); | 3251 ? current_map->elements_kind() == to_kind |
| 3252 : current_map->elements_kind() == TERMINAL_FAST_ELEMENTS_KIND); |
3260 return current_map; | 3253 return current_map; |
3261 } | 3254 } |
3262 | 3255 |
3263 | 3256 |
3264 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { | 3257 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { |
3265 Map* to_map = FindClosestElementsTransition(this, to_kind); | 3258 Map* to_map = FindClosestElementsTransition(this, to_kind); |
3266 if (to_map->elements_kind() == to_kind) return to_map; | 3259 if (to_map->elements_kind() == to_kind) return to_map; |
3267 return NULL; | 3260 return NULL; |
3268 } | 3261 } |
3269 | 3262 |
3270 | 3263 |
3271 bool Map::IsMapInArrayPrototypeChain() { | 3264 bool Map::IsMapInArrayPrototypeChain() { |
3272 Isolate* isolate = GetIsolate(); | 3265 Isolate* isolate = GetIsolate(); |
3273 if (isolate->initial_array_prototype()->map() == this) { | 3266 if (isolate->initial_array_prototype()->map() == this) { |
3274 return true; | 3267 return true; |
3275 } | 3268 } |
3276 | 3269 |
3277 if (isolate->initial_object_prototype()->map() == this) { | 3270 if (isolate->initial_object_prototype()->map() == this) { |
3278 return true; | 3271 return true; |
3279 } | 3272 } |
3280 | 3273 |
3281 return false; | 3274 return false; |
3282 } | 3275 } |
3283 | 3276 |
3284 | 3277 |
3285 static MaybeObject* AddMissingElementsTransitions(Map* map, | 3278 static MaybeObject* AddMissingElementsTransitions(Map* map, |
3286 ElementsKind to_kind) { | 3279 ElementsKind to_kind) { |
3287 ASSERT(IsTransitionElementsKind(map->elements_kind())); | 3280 ASSERT(IsFastElementsKind(map->elements_kind())); |
| 3281 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); |
| 3282 int to_index = IsFastElementsKind(to_kind) |
| 3283 ? GetSequenceIndexFromFastElementsKind(to_kind) |
| 3284 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); |
| 3285 |
| 3286 ASSERT(index <= to_index); |
3288 | 3287 |
3289 Map* current_map = map; | 3288 Map* current_map = map; |
3290 | 3289 |
3291 ElementsKind kind = map->elements_kind(); | 3290 for (; index < to_index; ++index) { |
3292 while (kind != to_kind && !IsTerminalElementsKind(kind)) { | 3291 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index + 1); |
3293 kind = GetNextTransitionElementsKind(kind); | |
3294 MaybeObject* maybe_next_map = | 3292 MaybeObject* maybe_next_map = |
3295 current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); | 3293 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); |
3296 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3294 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
3297 } | 3295 } |
3298 | 3296 |
3299 // In case we are exiting the fast elements kind system, just add the map in | 3297 // In case we are exiting the fast elements kind system, just add the map in |
3300 // the end. | 3298 // the end. |
3301 if (kind != to_kind) { | 3299 if (!IsFastElementsKind(to_kind)) { |
3302 MaybeObject* maybe_next_map = | 3300 MaybeObject* maybe_next_map = |
3303 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); | 3301 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); |
3304 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3302 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
3305 } | 3303 } |
3306 | 3304 |
3307 ASSERT(current_map->elements_kind() == to_kind); | 3305 ASSERT(current_map->elements_kind() == to_kind); |
3308 return current_map; | 3306 return current_map; |
3309 } | 3307 } |
3310 | 3308 |
3311 | 3309 |
(...skipping 11 matching lines...) Expand all Loading... |
3323 ElementsKind from_kind = start_map->elements_kind(); | 3321 ElementsKind from_kind = start_map->elements_kind(); |
3324 | 3322 |
3325 if (from_kind == to_kind) { | 3323 if (from_kind == to_kind) { |
3326 return start_map; | 3324 return start_map; |
3327 } | 3325 } |
3328 | 3326 |
3329 bool allow_store_transition = | 3327 bool allow_store_transition = |
3330 // Only remember the map transition if there is not an already existing | 3328 // Only remember the map transition if there is not an already existing |
3331 // non-matching element transition. | 3329 // non-matching element transition. |
3332 !start_map->IsUndefined() && !start_map->is_shared() && | 3330 !start_map->IsUndefined() && !start_map->is_shared() && |
3333 IsTransitionElementsKind(from_kind); | 3331 IsFastElementsKind(from_kind); |
3334 | 3332 |
3335 // Only store fast element maps in ascending generality. | 3333 // Only store fast element maps in ascending generality. |
3336 if (IsFastElementsKind(to_kind)) { | 3334 if (IsFastElementsKind(to_kind)) { |
3337 allow_store_transition &= | 3335 allow_store_transition &= |
3338 IsTransitionableFastElementsKind(from_kind) && | 3336 IsTransitionableFastElementsKind(from_kind) && |
3339 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 3337 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
3340 } | 3338 } |
3341 | 3339 |
3342 if (!allow_store_transition) { | 3340 if (!allow_store_transition) { |
3343 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); | 3341 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); |
(...skipping 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4695 dictionary = | 4693 dictionary = |
4696 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); | 4694 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); |
4697 } | 4695 } |
4698 } | 4696 } |
4699 return dictionary; | 4697 return dictionary; |
4700 } | 4698 } |
4701 | 4699 |
4702 | 4700 |
4703 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4701 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
4704 Handle<JSObject> object) { | 4702 Handle<JSObject> object) { |
4705 ASSERT(!object->HasExternalArrayElements() && | 4703 ASSERT(!object->HasExternalArrayElements()); |
4706 !object->HasFixedTypedArrayElements()); | |
4707 Isolate* isolate = object->GetIsolate(); | 4704 Isolate* isolate = object->GetIsolate(); |
4708 Factory* factory = isolate->factory(); | 4705 Factory* factory = isolate->factory(); |
4709 | 4706 |
4710 // Find the backing store. | 4707 // Find the backing store. |
4711 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); | 4708 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); |
4712 bool is_arguments = | 4709 bool is_arguments = |
4713 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); | 4710 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); |
4714 if (is_arguments) { | 4711 if (is_arguments) { |
4715 array = handle(FixedArrayBase::cast( | 4712 array = handle(FixedArrayBase::cast( |
4716 Handle<FixedArray>::cast(array)->get(1))); | 4713 Handle<FixedArray>::cast(array)->get(1))); |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5431 } | 5428 } |
5432 | 5429 |
5433 if (object->IsJSGlobalProxy()) { | 5430 if (object->IsJSGlobalProxy()) { |
5434 Handle<Object> proto(object->GetPrototype(), isolate); | 5431 Handle<Object> proto(object->GetPrototype(), isolate); |
5435 if (proto->IsNull()) return object; | 5432 if (proto->IsNull()) return object; |
5436 ASSERT(proto->IsJSGlobalObject()); | 5433 ASSERT(proto->IsJSGlobalObject()); |
5437 return PreventExtensions(Handle<JSObject>::cast(proto)); | 5434 return PreventExtensions(Handle<JSObject>::cast(proto)); |
5438 } | 5435 } |
5439 | 5436 |
5440 // It's not possible to seal objects with external array elements | 5437 // It's not possible to seal objects with external array elements |
5441 if (object->HasExternalArrayElements() || | 5438 if (object->HasExternalArrayElements()) { |
5442 object->HasFixedTypedArrayElements()) { | |
5443 Handle<Object> error = | 5439 Handle<Object> error = |
5444 isolate->factory()->NewTypeError( | 5440 isolate->factory()->NewTypeError( |
5445 "cant_prevent_ext_external_array_elements", | 5441 "cant_prevent_ext_external_array_elements", |
5446 HandleVector(&object, 1)); | 5442 HandleVector(&object, 1)); |
5447 isolate->Throw(*error); | 5443 isolate->Throw(*error); |
5448 return Handle<Object>(); | 5444 return Handle<Object>(); |
5449 } | 5445 } |
5450 | 5446 |
5451 // If there are fast elements we normalize. | 5447 // If there are fast elements we normalize. |
5452 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 5448 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5512 } | 5508 } |
5513 | 5509 |
5514 if (object->IsJSGlobalProxy()) { | 5510 if (object->IsJSGlobalProxy()) { |
5515 Handle<Object> proto(object->GetPrototype(), isolate); | 5511 Handle<Object> proto(object->GetPrototype(), isolate); |
5516 if (proto->IsNull()) return object; | 5512 if (proto->IsNull()) return object; |
5517 ASSERT(proto->IsJSGlobalObject()); | 5513 ASSERT(proto->IsJSGlobalObject()); |
5518 return Freeze(Handle<JSObject>::cast(proto)); | 5514 return Freeze(Handle<JSObject>::cast(proto)); |
5519 } | 5515 } |
5520 | 5516 |
5521 // It's not possible to freeze objects with external array elements | 5517 // It's not possible to freeze objects with external array elements |
5522 if (object->HasExternalArrayElements() || | 5518 if (object->HasExternalArrayElements()) { |
5523 object->HasFixedTypedArrayElements()) { | |
5524 Handle<Object> error = | 5519 Handle<Object> error = |
5525 isolate->factory()->NewTypeError( | 5520 isolate->factory()->NewTypeError( |
5526 "cant_prevent_ext_external_array_elements", | 5521 "cant_prevent_ext_external_array_elements", |
5527 HandleVector(&object, 1)); | 5522 HandleVector(&object, 1)); |
5528 isolate->Throw(*error); | 5523 isolate->Throw(*error); |
5529 return Handle<Object>(); | 5524 return Handle<Object>(); |
5530 } | 5525 } |
5531 | 5526 |
5532 Handle<SeededNumberDictionary> new_element_dictionary; | 5527 Handle<SeededNumberDictionary> new_element_dictionary; |
5533 if (!object->elements()->IsDictionary()) { | 5528 if (!object->elements()->IsDictionary()) { |
(...skipping 6942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12476 Handle<Object> proto(object->GetPrototype(), isolate); | 12471 Handle<Object> proto(object->GetPrototype(), isolate); |
12477 if (proto->IsNull()) return value; | 12472 if (proto->IsNull()) return value; |
12478 ASSERT(proto->IsJSGlobalObject()); | 12473 ASSERT(proto->IsJSGlobalObject()); |
12479 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, | 12474 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
12480 strict_mode, | 12475 strict_mode, |
12481 check_prototype, | 12476 check_prototype, |
12482 set_mode); | 12477 set_mode); |
12483 } | 12478 } |
12484 | 12479 |
12485 // Don't allow element properties to be redefined for external arrays. | 12480 // Don't allow element properties to be redefined for external arrays. |
12486 if ((object->HasExternalArrayElements() || | 12481 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { |
12487 object->HasFixedTypedArrayElements()) && | |
12488 set_mode == DEFINE_PROPERTY) { | |
12489 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12482 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12490 Handle<Object> args[] = { object, number }; | 12483 Handle<Object> args[] = { object, number }; |
12491 Handle<Object> error = isolate->factory()->NewTypeError( | 12484 Handle<Object> error = isolate->factory()->NewTypeError( |
12492 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12485 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
12493 isolate->Throw(*error); | 12486 isolate->Throw(*error); |
12494 return Handle<Object>(); | 12487 return Handle<Object>(); |
12495 } | 12488 } |
12496 | 12489 |
12497 // Normalize the elements to enable attributes on the property. | 12490 // Normalize the elements to enable attributes on the property. |
12498 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12491 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
(...skipping 1913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14412 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); | 14405 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); |
14413 | 14406 |
14414 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? | 14407 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? |
14415 NOT_TENURED: TENURED; | 14408 NOT_TENURED: TENURED; |
14416 Handle<FixedArray> fast_elements = | 14409 Handle<FixedArray> fast_elements = |
14417 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14410 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
14418 dict->CopyValuesTo(*fast_elements); | 14411 dict->CopyValuesTo(*fast_elements); |
14419 object->ValidateElements(); | 14412 object->ValidateElements(); |
14420 | 14413 |
14421 object->set_map_and_elements(*new_map, *fast_elements); | 14414 object->set_map_and_elements(*new_map, *fast_elements); |
14422 } else if (object->HasExternalArrayElements() || | 14415 } else if (object->HasExternalArrayElements()) { |
14423 object->HasFixedTypedArrayElements()) { | 14416 // External arrays cannot have holes or undefined elements. |
14424 // Typed arrays cannot have holes or undefined elements. | |
14425 return handle(Smi::FromInt( | 14417 return handle(Smi::FromInt( |
14426 FixedArrayBase::cast(object->elements())->length()), isolate); | 14418 ExternalArray::cast(object->elements())->length()), isolate); |
14427 } else if (!object->HasFastDoubleElements()) { | 14419 } else if (!object->HasFastDoubleElements()) { |
14428 EnsureWritableFastElements(object); | 14420 EnsureWritableFastElements(object); |
14429 } | 14421 } |
14430 ASSERT(object->HasFastSmiOrObjectElements() || | 14422 ASSERT(object->HasFastSmiOrObjectElements() || |
14431 object->HasFastDoubleElements()); | 14423 object->HasFastDoubleElements()); |
14432 | 14424 |
14433 // Collect holes at the end, undefined before that and the rest at the | 14425 // Collect holes at the end, undefined before that and the rest at the |
14434 // start, and return the number of non-hole, non-undefined values. | 14426 // start, and return the number of non-hole, non-undefined values. |
14435 | 14427 |
14436 Handle<FixedArrayBase> elements_base(object->elements()); | 14428 Handle<FixedArrayBase> elements_base(object->elements()); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14517 } | 14509 } |
14518 | 14510 |
14519 return isolate->factory()->NewNumberFromUint(result); | 14511 return isolate->factory()->NewNumberFromUint(result); |
14520 } | 14512 } |
14521 | 14513 |
14522 | 14514 |
14523 ExternalArrayType JSTypedArray::type() { | 14515 ExternalArrayType JSTypedArray::type() { |
14524 switch (elements()->map()->instance_type()) { | 14516 switch (elements()->map()->instance_type()) { |
14525 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ | 14517 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ |
14526 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14518 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
14527 case FIXED_##TYPE##_ARRAY_TYPE: \ | |
14528 return kExternal##Type##Array; | 14519 return kExternal##Type##Array; |
14529 | 14520 |
14530 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) | 14521 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) |
14531 #undef INSTANCE_TYPE_TO_ARRAY_TYPE | 14522 #undef INSTANCE_TYPE_TO_ARRAY_TYPE |
14532 | 14523 |
14533 default: | 14524 default: |
14534 UNREACHABLE(); | |
14535 return static_cast<ExternalArrayType>(-1); | 14525 return static_cast<ExternalArrayType>(-1); |
14536 } | 14526 } |
14537 } | 14527 } |
14538 | 14528 |
14539 | 14529 |
14540 size_t JSTypedArray::element_size() { | 14530 size_t JSTypedArray::element_size() { |
14541 switch (elements()->map()->instance_type()) { | 14531 switch (elements()->map()->instance_type()) { |
14542 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ | 14532 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ |
14543 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14533 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
14544 return size; | 14534 return size; |
(...skipping 1818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16363 } | 16353 } |
16364 | 16354 |
16365 | 16355 |
16366 void JSTypedArray::Neuter() { | 16356 void JSTypedArray::Neuter() { |
16367 NeuterView(); | 16357 NeuterView(); |
16368 set_length(Smi::FromInt(0)); | 16358 set_length(Smi::FromInt(0)); |
16369 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); | 16359 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); |
16370 } | 16360 } |
16371 | 16361 |
16372 | 16362 |
16373 static ElementsKind FixedToExternalElementsKind(ElementsKind elements_kind) { | |
16374 switch (elements_kind) { | |
16375 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | |
16376 case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS; | |
16377 | |
16378 TYPED_ARRAYS(TYPED_ARRAY_CASE) | |
16379 #undef TYPED_ARRAY_CASE | |
16380 | |
16381 default: | |
16382 UNREACHABLE(); | |
16383 return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND; | |
16384 } | |
16385 } | |
16386 | |
16387 | |
16388 Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer( | |
16389 Handle<JSTypedArray> typed_array) { | |
16390 | |
16391 Handle<Map> map(typed_array->map()); | |
16392 Isolate* isolate = typed_array->GetIsolate(); | |
16393 | |
16394 ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind())); | |
16395 | |
16396 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | |
16397 Handle<FixedTypedArrayBase> fixed_typed_array( | |
16398 FixedTypedArrayBase::cast(typed_array->elements())); | |
16399 Runtime::SetupArrayBufferAllocatingData(isolate, buffer, | |
16400 fixed_typed_array->DataSize(), false); | |
16401 memcpy(buffer->backing_store(), | |
16402 fixed_typed_array->DataPtr(), | |
16403 fixed_typed_array->DataSize()); | |
16404 Handle<ExternalArray> new_elements = | |
16405 isolate->factory()->NewExternalArray( | |
16406 fixed_typed_array->length(), typed_array->type(), | |
16407 static_cast<uint8_t*>(buffer->backing_store())); | |
16408 Handle<Map> new_map = | |
16409 isolate->factory()->GetElementsTransitionMap( | |
16410 typed_array, | |
16411 FixedToExternalElementsKind(map->elements_kind())); | |
16412 | |
16413 buffer->set_weak_first_view(*typed_array); | |
16414 ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value()); | |
16415 typed_array->set_buffer(*buffer); | |
16416 typed_array->set_map_and_elements(*new_map, *new_elements); | |
16417 | |
16418 return buffer; | |
16419 } | |
16420 | |
16421 | |
16422 Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { | |
16423 Handle<Object> result(buffer(), GetIsolate()); | |
16424 if (*result != Smi::FromInt(0)) { | |
16425 ASSERT(IsExternalArrayElementsKind(map()->elements_kind())); | |
16426 return Handle<JSArrayBuffer>::cast(result); | |
16427 } | |
16428 Handle<JSTypedArray> self(this); | |
16429 return MaterializeArrayBuffer(self); | |
16430 } | |
16431 | |
16432 | |
16433 HeapType* PropertyCell::type() { | 16363 HeapType* PropertyCell::type() { |
16434 return static_cast<HeapType*>(type_raw()); | 16364 return static_cast<HeapType*>(type_raw()); |
16435 } | 16365 } |
16436 | 16366 |
16437 | 16367 |
16438 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { | 16368 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { |
16439 ASSERT(IsPropertyCell()); | 16369 ASSERT(IsPropertyCell()); |
16440 set_type_raw(type, ignored); | 16370 set_type_raw(type, ignored); |
16441 } | 16371 } |
16442 | 16372 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16491 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16421 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16492 static const char* error_messages_[] = { | 16422 static const char* error_messages_[] = { |
16493 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16423 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16494 }; | 16424 }; |
16495 #undef ERROR_MESSAGES_TEXTS | 16425 #undef ERROR_MESSAGES_TEXTS |
16496 return error_messages_[reason]; | 16426 return error_messages_[reason]; |
16497 } | 16427 } |
16498 | 16428 |
16499 | 16429 |
16500 } } // namespace v8::internal | 16430 } } // namespace v8::internal |
OLD | NEW |