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 |