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 |