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 3238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3249 } | 3249 } |
3250 current_map = maybe_transitioned_map; | 3250 current_map = maybe_transitioned_map; |
3251 } | 3251 } |
3252 } | 3252 } |
3253 return transitioned_map; | 3253 return transitioned_map; |
3254 } | 3254 } |
3255 | 3255 |
3256 | 3256 |
3257 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 3257 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
3258 Map* current_map = map; | 3258 Map* current_map = map; |
3259 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); | 3259 int target_kind = |
3260 int to_index = IsFastElementsKind(to_kind) | 3260 IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind) |
Toon Verwaest
2014/03/10 14:15:34
IsTransitionElementsKind(to_kind)?
Dmitry Lomov (no reviews)
2014/03/24 08:31:22
No, this is not IsTransitionElementsKind.
| |
3261 ? GetSequenceIndexFromFastElementsKind(to_kind) | 3261 ? to_kind |
3262 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); | 3262 : TERMINAL_FAST_ELEMENTS_KIND; |
3263 | 3263 |
3264 ASSERT(index <= to_index); | 3264 // Support for legacy API. |
3265 if (IsExternalArrayElementsKind(to_kind) && | |
3266 !IsFixedTypedArrayElementsKind(map->elements_kind())) { | |
3267 return map; | |
3268 } | |
3265 | 3269 |
3266 for (; index < to_index; ++index) { | 3270 ElementsKind kind = map->elements_kind(); |
3271 while (kind != target_kind) { | |
3272 kind = GetNextTransitionElementsKind(kind); | |
3267 if (!current_map->HasElementsTransition()) return current_map; | 3273 if (!current_map->HasElementsTransition()) return current_map; |
3268 current_map = current_map->elements_transition_map(); | 3274 current_map = current_map->elements_transition_map(); |
3269 } | 3275 } |
3270 if (!IsFastElementsKind(to_kind) && current_map->HasElementsTransition()) { | 3276 |
3277 if (to_kind != kind && current_map->HasElementsTransition()) { | |
Toon Verwaest
2014/03/10 14:15:34
Can this only happen for DICTIONARY elements now?
Dmitry Lomov (no reviews)
2014/03/24 08:31:22
Done.
| |
3271 Map* next_map = current_map->elements_transition_map(); | 3278 Map* next_map = current_map->elements_transition_map(); |
3272 if (next_map->elements_kind() == to_kind) return next_map; | 3279 if (next_map->elements_kind() == to_kind) return next_map; |
3273 } | 3280 } |
3274 ASSERT(IsFastElementsKind(to_kind) | 3281 |
3275 ? current_map->elements_kind() == to_kind | 3282 ASSERT(current_map->elements_kind() == target_kind); |
Toon Verwaest
2014/03/10 14:15:34
This ASSERT is wrong afaict. If we didnt' have an
Dmitry Lomov (no reviews)
2014/03/24 08:31:22
target_kind is not DICTIONARY_ELEMENTS in that cas
| |
3276 : current_map->elements_kind() == TERMINAL_FAST_ELEMENTS_KIND); | |
3277 return current_map; | 3283 return current_map; |
3278 } | 3284 } |
3279 | 3285 |
3280 | 3286 |
3281 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { | 3287 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { |
3282 Map* to_map = FindClosestElementsTransition(this, to_kind); | 3288 Map* to_map = FindClosestElementsTransition(this, to_kind); |
3283 if (to_map->elements_kind() == to_kind) return to_map; | 3289 if (to_map->elements_kind() == to_kind) return to_map; |
3284 return NULL; | 3290 return NULL; |
3285 } | 3291 } |
3286 | 3292 |
3287 | 3293 |
3288 bool Map::IsMapInArrayPrototypeChain() { | 3294 bool Map::IsMapInArrayPrototypeChain() { |
3289 Isolate* isolate = GetIsolate(); | 3295 Isolate* isolate = GetIsolate(); |
3290 if (isolate->initial_array_prototype()->map() == this) { | 3296 if (isolate->initial_array_prototype()->map() == this) { |
3291 return true; | 3297 return true; |
3292 } | 3298 } |
3293 | 3299 |
3294 if (isolate->initial_object_prototype()->map() == this) { | 3300 if (isolate->initial_object_prototype()->map() == this) { |
3295 return true; | 3301 return true; |
3296 } | 3302 } |
3297 | 3303 |
3298 return false; | 3304 return false; |
3299 } | 3305 } |
3300 | 3306 |
3301 | 3307 |
3302 static MaybeObject* AddMissingElementsTransitions(Map* map, | 3308 static MaybeObject* AddMissingElementsTransitions(Map* map, |
3303 ElementsKind to_kind) { | 3309 ElementsKind to_kind) { |
3304 ASSERT(IsFastElementsKind(map->elements_kind())); | 3310 ASSERT(IsTransitionElementsKind(map->elements_kind())); |
3305 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); | |
3306 int to_index = IsFastElementsKind(to_kind) | |
3307 ? GetSequenceIndexFromFastElementsKind(to_kind) | |
3308 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); | |
3309 | |
3310 ASSERT(index <= to_index); | |
3311 | 3311 |
3312 Map* current_map = map; | 3312 Map* current_map = map; |
3313 | 3313 |
3314 for (; index < to_index; ++index) { | 3314 ElementsKind kind = map->elements_kind(); |
3315 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index + 1); | 3315 while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
3316 kind = GetNextTransitionElementsKind(kind); | |
3316 MaybeObject* maybe_next_map = | 3317 MaybeObject* maybe_next_map = |
3317 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); | 3318 current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); |
3318 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3319 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
3319 } | 3320 } |
3320 | 3321 |
3321 // In case we are exiting the fast elements kind system, just add the map in | 3322 // In case we are exiting the fast elements kind system, just add the map in |
3322 // the end. | 3323 // the end. |
3323 if (!IsFastElementsKind(to_kind)) { | 3324 if (kind != to_kind) { |
Toon Verwaest
2014/03/10 14:15:34
Can this only happen for DICTIONARY elements now?
Dmitry Lomov (no reviews)
2014/03/24 08:31:22
No, this happens at the end of all chains.
| |
3324 MaybeObject* maybe_next_map = | 3325 MaybeObject* maybe_next_map = |
3325 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); | 3326 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); |
3326 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3327 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
3327 } | 3328 } |
3328 | 3329 |
3329 ASSERT(current_map->elements_kind() == to_kind); | 3330 ASSERT(current_map->elements_kind() == to_kind); |
3330 return current_map; | 3331 return current_map; |
3331 } | 3332 } |
3332 | 3333 |
3333 | 3334 |
(...skipping 11 matching lines...) Expand all Loading... | |
3345 ElementsKind from_kind = start_map->elements_kind(); | 3346 ElementsKind from_kind = start_map->elements_kind(); |
3346 | 3347 |
3347 if (from_kind == to_kind) { | 3348 if (from_kind == to_kind) { |
3348 return start_map; | 3349 return start_map; |
3349 } | 3350 } |
3350 | 3351 |
3351 bool allow_store_transition = | 3352 bool allow_store_transition = |
3352 // Only remember the map transition if there is not an already existing | 3353 // Only remember the map transition if there is not an already existing |
3353 // non-matching element transition. | 3354 // non-matching element transition. |
3354 !start_map->IsUndefined() && !start_map->is_shared() && | 3355 !start_map->IsUndefined() && !start_map->is_shared() && |
3355 IsFastElementsKind(from_kind); | 3356 IsTransitionElementsKind(from_kind); |
3356 | 3357 |
3357 // Only store fast element maps in ascending generality. | 3358 // Only store fast element maps in ascending generality. |
3358 if (IsFastElementsKind(to_kind)) { | 3359 if (IsFastElementsKind(to_kind)) { |
3359 allow_store_transition &= | 3360 allow_store_transition &= |
3360 IsTransitionableFastElementsKind(from_kind) && | 3361 IsTransitionableFastElementsKind(from_kind) && |
3361 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 3362 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
3362 } | 3363 } |
3363 | 3364 |
3364 if (!allow_store_transition) { | 3365 if (!allow_store_transition) { |
3365 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); | 3366 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); |
3366 } | 3367 } |
3367 | 3368 |
3368 return start_map->AsElementsKind(to_kind); | 3369 return start_map->AsElementsKind(to_kind); |
3369 } | 3370 } |
3370 | 3371 |
3371 | 3372 |
3372 MaybeObject* Map::AsElementsKind(ElementsKind kind) { | 3373 MaybeObject* Map::AsElementsKind(ElementsKind kind) { |
3373 Map* closest_map = FindClosestElementsTransition(this, kind); | 3374 Map* closest_map = FindClosestElementsTransition(this, kind); |
3374 | 3375 |
3375 if (closest_map->elements_kind() == kind) { | 3376 if (closest_map->elements_kind() == kind) { |
3376 return closest_map; | 3377 return closest_map; |
3377 } | 3378 } |
3378 | 3379 |
3379 return AddMissingElementsTransitions(closest_map, kind); | 3380 return AddMissingElementsTransitions(closest_map, kind); |
3380 } | 3381 } |
3381 | 3382 |
3382 | 3383 |
3384 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { | |
3385 CALL_HEAP_FUNCTION(map->GetIsolate(), map->AsElementsKind(kind), Map); | |
3386 } | |
3387 | |
3388 | |
3383 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { | 3389 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { |
3384 DisallowHeapAllocation no_gc; | 3390 DisallowHeapAllocation no_gc; |
3385 if (IsJSGlobalProxy()) { | 3391 if (IsJSGlobalProxy()) { |
3386 Object* proto = GetPrototype(); | 3392 Object* proto = GetPrototype(); |
3387 if (proto->IsNull()) return result->NotFound(); | 3393 if (proto->IsNull()) return result->NotFound(); |
3388 ASSERT(proto->IsJSGlobalObject()); | 3394 ASSERT(proto->IsJSGlobalObject()); |
3389 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); | 3395 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); |
3390 } | 3396 } |
3391 | 3397 |
3392 if (HasFastProperties()) { | 3398 if (HasFastProperties()) { |
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4722 | 4728 |
4723 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4729 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
4724 Handle<JSObject> object) { | 4730 Handle<JSObject> object) { |
4725 CALL_HEAP_FUNCTION(object->GetIsolate(), | 4731 CALL_HEAP_FUNCTION(object->GetIsolate(), |
4726 object->NormalizeElements(), | 4732 object->NormalizeElements(), |
4727 SeededNumberDictionary); | 4733 SeededNumberDictionary); |
4728 } | 4734 } |
4729 | 4735 |
4730 | 4736 |
4731 MaybeObject* JSObject::NormalizeElements() { | 4737 MaybeObject* JSObject::NormalizeElements() { |
4732 ASSERT(!HasExternalArrayElements()); | 4738 ASSERT(!HasExternalArrayElements() && !HasFixedTypedArrayElements()); |
4733 | 4739 |
4734 // Find the backing store. | 4740 // Find the backing store. |
4735 FixedArrayBase* array = FixedArrayBase::cast(elements()); | 4741 FixedArrayBase* array = FixedArrayBase::cast(elements()); |
4736 Map* old_map = array->map(); | 4742 Map* old_map = array->map(); |
4737 bool is_arguments = | 4743 bool is_arguments = |
4738 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); | 4744 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); |
4739 if (is_arguments) { | 4745 if (is_arguments) { |
4740 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); | 4746 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); |
4741 } | 4747 } |
4742 if (array->IsDictionary()) return array; | 4748 if (array->IsDictionary()) return array; |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5468 } | 5474 } |
5469 | 5475 |
5470 if (object->IsJSGlobalProxy()) { | 5476 if (object->IsJSGlobalProxy()) { |
5471 Handle<Object> proto(object->GetPrototype(), isolate); | 5477 Handle<Object> proto(object->GetPrototype(), isolate); |
5472 if (proto->IsNull()) return object; | 5478 if (proto->IsNull()) return object; |
5473 ASSERT(proto->IsJSGlobalObject()); | 5479 ASSERT(proto->IsJSGlobalObject()); |
5474 return PreventExtensions(Handle<JSObject>::cast(proto)); | 5480 return PreventExtensions(Handle<JSObject>::cast(proto)); |
5475 } | 5481 } |
5476 | 5482 |
5477 // It's not possible to seal objects with external array elements | 5483 // It's not possible to seal objects with external array elements |
5478 if (object->HasExternalArrayElements()) { | 5484 if (object->HasExternalArrayElements() || |
5485 object->HasFixedTypedArrayElements()) { | |
5479 Handle<Object> error = | 5486 Handle<Object> error = |
5480 isolate->factory()->NewTypeError( | 5487 isolate->factory()->NewTypeError( |
5481 "cant_prevent_ext_external_array_elements", | 5488 "cant_prevent_ext_external_array_elements", |
5482 HandleVector(&object, 1)); | 5489 HandleVector(&object, 1)); |
5483 isolate->Throw(*error); | 5490 isolate->Throw(*error); |
5484 return Handle<Object>(); | 5491 return Handle<Object>(); |
5485 } | 5492 } |
5486 | 5493 |
5487 // If there are fast elements we normalize. | 5494 // If there are fast elements we normalize. |
5488 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 5495 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5548 } | 5555 } |
5549 | 5556 |
5550 if (object->IsJSGlobalProxy()) { | 5557 if (object->IsJSGlobalProxy()) { |
5551 Handle<Object> proto(object->GetPrototype(), isolate); | 5558 Handle<Object> proto(object->GetPrototype(), isolate); |
5552 if (proto->IsNull()) return object; | 5559 if (proto->IsNull()) return object; |
5553 ASSERT(proto->IsJSGlobalObject()); | 5560 ASSERT(proto->IsJSGlobalObject()); |
5554 return Freeze(Handle<JSObject>::cast(proto)); | 5561 return Freeze(Handle<JSObject>::cast(proto)); |
5555 } | 5562 } |
5556 | 5563 |
5557 // It's not possible to freeze objects with external array elements | 5564 // It's not possible to freeze objects with external array elements |
5558 if (object->HasExternalArrayElements()) { | 5565 if (object->HasExternalArrayElements() || |
5566 object->HasFixedTypedArrayElements()) { | |
5559 Handle<Object> error = | 5567 Handle<Object> error = |
5560 isolate->factory()->NewTypeError( | 5568 isolate->factory()->NewTypeError( |
5561 "cant_prevent_ext_external_array_elements", | 5569 "cant_prevent_ext_external_array_elements", |
5562 HandleVector(&object, 1)); | 5570 HandleVector(&object, 1)); |
5563 isolate->Throw(*error); | 5571 isolate->Throw(*error); |
5564 return Handle<Object>(); | 5572 return Handle<Object>(); |
5565 } | 5573 } |
5566 | 5574 |
5567 Handle<SeededNumberDictionary> new_element_dictionary; | 5575 Handle<SeededNumberDictionary> new_element_dictionary; |
5568 if (!object->elements()->IsDictionary()) { | 5576 if (!object->elements()->IsDictionary()) { |
(...skipping 6960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12529 Handle<Object> proto(object->GetPrototype(), isolate); | 12537 Handle<Object> proto(object->GetPrototype(), isolate); |
12530 if (proto->IsNull()) return value; | 12538 if (proto->IsNull()) return value; |
12531 ASSERT(proto->IsJSGlobalObject()); | 12539 ASSERT(proto->IsJSGlobalObject()); |
12532 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, | 12540 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
12533 strict_mode, | 12541 strict_mode, |
12534 check_prototype, | 12542 check_prototype, |
12535 set_mode); | 12543 set_mode); |
12536 } | 12544 } |
12537 | 12545 |
12538 // Don't allow element properties to be redefined for external arrays. | 12546 // Don't allow element properties to be redefined for external arrays. |
12539 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 12547 if ((object->HasExternalArrayElements() || |
12548 object->HasFixedTypedArrayElements()) && | |
12549 set_mode == DEFINE_PROPERTY) { | |
12540 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12550 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12541 Handle<Object> args[] = { object, number }; | 12551 Handle<Object> args[] = { object, number }; |
12542 Handle<Object> error = isolate->factory()->NewTypeError( | 12552 Handle<Object> error = isolate->factory()->NewTypeError( |
12543 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12553 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
12544 isolate->Throw(*error); | 12554 isolate->Throw(*error); |
12545 return Handle<Object>(); | 12555 return Handle<Object>(); |
12546 } | 12556 } |
12547 | 12557 |
12548 // Normalize the elements to enable attributes on the property. | 12558 // Normalize the elements to enable attributes on the property. |
12549 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12559 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
(...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14466 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); | 14476 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); |
14467 | 14477 |
14468 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? | 14478 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? |
14469 NOT_TENURED: TENURED; | 14479 NOT_TENURED: TENURED; |
14470 Handle<FixedArray> fast_elements = | 14480 Handle<FixedArray> fast_elements = |
14471 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14481 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
14472 dict->CopyValuesTo(*fast_elements); | 14482 dict->CopyValuesTo(*fast_elements); |
14473 object->ValidateElements(); | 14483 object->ValidateElements(); |
14474 | 14484 |
14475 object->set_map_and_elements(*new_map, *fast_elements); | 14485 object->set_map_and_elements(*new_map, *fast_elements); |
14476 } else if (object->HasExternalArrayElements()) { | 14486 } else if (object->HasExternalArrayElements() || |
14477 // External arrays cannot have holes or undefined elements. | 14487 object->HasFixedTypedArrayElements()) { |
14488 // Typed arrays cannot have holes or undefined elements. | |
14478 return handle(Smi::FromInt( | 14489 return handle(Smi::FromInt( |
14479 ExternalArray::cast(object->elements())->length()), isolate); | 14490 FixedArrayBase::cast(object->elements())->length()), isolate); |
14480 } else if (!object->HasFastDoubleElements()) { | 14491 } else if (!object->HasFastDoubleElements()) { |
14481 EnsureWritableFastElements(object); | 14492 EnsureWritableFastElements(object); |
14482 } | 14493 } |
14483 ASSERT(object->HasFastSmiOrObjectElements() || | 14494 ASSERT(object->HasFastSmiOrObjectElements() || |
14484 object->HasFastDoubleElements()); | 14495 object->HasFastDoubleElements()); |
14485 | 14496 |
14486 // Collect holes at the end, undefined before that and the rest at the | 14497 // Collect holes at the end, undefined before that and the rest at the |
14487 // start, and return the number of non-hole, non-undefined values. | 14498 // start, and return the number of non-hole, non-undefined values. |
14488 | 14499 |
14489 Handle<FixedArrayBase> elements_base(object->elements()); | 14500 Handle<FixedArrayBase> elements_base(object->elements()); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14570 } | 14581 } |
14571 | 14582 |
14572 return isolate->factory()->NewNumberFromUint(result); | 14583 return isolate->factory()->NewNumberFromUint(result); |
14573 } | 14584 } |
14574 | 14585 |
14575 | 14586 |
14576 ExternalArrayType JSTypedArray::type() { | 14587 ExternalArrayType JSTypedArray::type() { |
14577 switch (elements()->map()->instance_type()) { | 14588 switch (elements()->map()->instance_type()) { |
14578 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ | 14589 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ |
14579 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14590 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
14591 case FIXED_##TYPE##_ARRAY_TYPE: \ | |
14580 return kExternal##Type##Array; | 14592 return kExternal##Type##Array; |
14581 | 14593 |
14582 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) | 14594 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) |
14583 #undef INSTANCE_TYPE_TO_ARRAY_TYPE | 14595 #undef INSTANCE_TYPE_TO_ARRAY_TYPE |
14584 | 14596 |
14585 default: | 14597 default: |
14598 UNREACHABLE(); | |
14586 return static_cast<ExternalArrayType>(-1); | 14599 return static_cast<ExternalArrayType>(-1); |
14587 } | 14600 } |
14588 } | 14601 } |
14589 | 14602 |
14590 | 14603 |
14591 size_t JSTypedArray::element_size() { | 14604 size_t JSTypedArray::element_size() { |
14592 switch (elements()->map()->instance_type()) { | 14605 switch (elements()->map()->instance_type()) { |
14593 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ | 14606 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ |
14594 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14607 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
14595 return size; | 14608 return size; |
(...skipping 1837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16433 } | 16446 } |
16434 | 16447 |
16435 | 16448 |
16436 void JSTypedArray::Neuter() { | 16449 void JSTypedArray::Neuter() { |
16437 NeuterView(); | 16450 NeuterView(); |
16438 set_length(Smi::FromInt(0)); | 16451 set_length(Smi::FromInt(0)); |
16439 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); | 16452 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); |
16440 } | 16453 } |
16441 | 16454 |
16442 | 16455 |
16456 static ElementsKind FixedToExternalElementsKind(ElementsKind elements_kind) { | |
16457 switch (elements_kind) { | |
16458 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | |
16459 case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS; | |
16460 | |
16461 TYPED_ARRAYS(TYPED_ARRAY_CASE) | |
16462 #undef TYPED_ARRAY_CASE | |
16463 | |
16464 default: | |
16465 UNREACHABLE(); | |
16466 return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND; | |
16467 } | |
16468 } | |
16469 | |
16470 | |
16471 Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer( | |
16472 Handle<JSTypedArray> typed_array) { | |
16473 | |
16474 Handle<Map> map(typed_array->map()); | |
16475 Isolate* isolate = typed_array->GetIsolate(); | |
16476 | |
16477 ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind())); | |
16478 | |
16479 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | |
16480 Handle<FixedTypedArrayBase> fixed_typed_array( | |
16481 FixedTypedArrayBase::cast(typed_array->elements())); | |
16482 Runtime::SetupArrayBufferAllocatingData(isolate, buffer, | |
16483 fixed_typed_array->DataSize(), false); | |
16484 memcpy(buffer->backing_store(), | |
16485 fixed_typed_array->DataPtr(), | |
16486 fixed_typed_array->DataSize()); | |
16487 Handle<ExternalArray> new_elements = | |
16488 isolate->factory()->NewExternalArray( | |
16489 fixed_typed_array->length(), typed_array->type(), | |
16490 static_cast<uint8_t*>(buffer->backing_store())); | |
16491 Handle<Map> new_map = | |
16492 isolate->factory()->GetElementsTransitionMap( | |
16493 typed_array, | |
16494 FixedToExternalElementsKind(map->elements_kind())); | |
16495 | |
16496 buffer->set_weak_first_view(*typed_array); | |
16497 ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value()); | |
16498 typed_array->set_buffer(*buffer); | |
16499 typed_array->set_map_and_elements(*new_map, *new_elements); | |
16500 | |
16501 return buffer; | |
16502 } | |
16503 | |
16504 | |
16505 Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { | |
16506 Handle<Object> result(buffer(), GetIsolate()); | |
16507 if (*result != Smi::FromInt(0)) { | |
16508 ASSERT(IsExternalArrayElementsKind(map()->elements_kind())); | |
16509 return Handle<JSArrayBuffer>::cast(result); | |
16510 } | |
16511 Handle<JSTypedArray> self(this); | |
16512 return MaterializeArrayBuffer(self); | |
16513 } | |
16514 | |
16515 | |
16443 HeapType* PropertyCell::type() { | 16516 HeapType* PropertyCell::type() { |
16444 return static_cast<HeapType*>(type_raw()); | 16517 return static_cast<HeapType*>(type_raw()); |
16445 } | 16518 } |
16446 | 16519 |
16447 | 16520 |
16448 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { | 16521 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { |
16449 ASSERT(IsPropertyCell()); | 16522 ASSERT(IsPropertyCell()); |
16450 set_type_raw(type, ignored); | 16523 set_type_raw(type, ignored); |
16451 } | 16524 } |
16452 | 16525 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16501 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16574 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16502 static const char* error_messages_[] = { | 16575 static const char* error_messages_[] = { |
16503 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16576 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16504 }; | 16577 }; |
16505 #undef ERROR_MESSAGES_TEXTS | 16578 #undef ERROR_MESSAGES_TEXTS |
16506 return error_messages_[reason]; | 16579 return error_messages_[reason]; |
16507 } | 16580 } |
16508 | 16581 |
16509 | 16582 |
16510 } } // namespace v8::internal | 16583 } } // namespace v8::internal |
OLD | NEW |