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 3242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3253 } | 3253 } |
3254 current_map = maybe_transitioned_map; | 3254 current_map = maybe_transitioned_map; |
3255 } | 3255 } |
3256 } | 3256 } |
3257 return transitioned_map; | 3257 return transitioned_map; |
3258 } | 3258 } |
3259 | 3259 |
3260 | 3260 |
3261 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 3261 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
3262 Map* current_map = map; | 3262 Map* current_map = map; |
3263 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); | 3263 int target_kind = |
3264 int to_index = IsFastElementsKind(to_kind) | 3264 IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind) |
3265 ? GetSequenceIndexFromFastElementsKind(to_kind) | 3265 ? to_kind |
3266 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); | 3266 : TERMINAL_FAST_ELEMENTS_KIND; |
3267 | 3267 |
3268 ASSERT(index <= to_index); | 3268 // Support for legacy API. |
3269 if (IsExternalArrayElementsKind(to_kind) && | |
3270 !IsFixedTypedArrayElementsKind(map->elements_kind())) { | |
3271 return map; | |
3272 } | |
3269 | 3273 |
3270 for (; index < to_index; ++index) { | 3274 ElementsKind kind = map->elements_kind(); |
3275 while (kind != target_kind) { | |
3276 kind = GetNextTransitionElementsKind(kind); | |
3271 if (!current_map->HasElementsTransition()) return current_map; | 3277 if (!current_map->HasElementsTransition()) return current_map; |
3272 current_map = current_map->elements_transition_map(); | 3278 current_map = current_map->elements_transition_map(); |
3273 } | 3279 } |
3274 if (!IsFastElementsKind(to_kind) && current_map->HasElementsTransition()) { | 3280 |
3281 if (to_kind != kind && current_map->HasElementsTransition()) { | |
3275 Map* next_map = current_map->elements_transition_map(); | 3282 Map* next_map = current_map->elements_transition_map(); |
3276 if (next_map->elements_kind() == to_kind) return next_map; | 3283 if (next_map->elements_kind() == to_kind) return next_map; |
3277 } | 3284 } |
3278 ASSERT(IsFastElementsKind(to_kind) | 3285 |
3279 ? current_map->elements_kind() == to_kind | 3286 ASSERT(current_map->elements_kind() == target_kind); |
3280 : current_map->elements_kind() == TERMINAL_FAST_ELEMENTS_KIND); | |
3281 return current_map; | 3287 return current_map; |
3282 } | 3288 } |
3283 | 3289 |
3284 | 3290 |
3285 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { | 3291 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { |
3286 Map* to_map = FindClosestElementsTransition(this, to_kind); | 3292 Map* to_map = FindClosestElementsTransition(this, to_kind); |
3287 if (to_map->elements_kind() == to_kind) return to_map; | 3293 if (to_map->elements_kind() == to_kind) return to_map; |
3288 return NULL; | 3294 return NULL; |
3289 } | 3295 } |
3290 | 3296 |
3291 | 3297 |
3292 bool Map::IsMapInArrayPrototypeChain() { | 3298 bool Map::IsMapInArrayPrototypeChain() { |
3293 Isolate* isolate = GetIsolate(); | 3299 Isolate* isolate = GetIsolate(); |
3294 if (isolate->initial_array_prototype()->map() == this) { | 3300 if (isolate->initial_array_prototype()->map() == this) { |
3295 return true; | 3301 return true; |
3296 } | 3302 } |
3297 | 3303 |
3298 if (isolate->initial_object_prototype()->map() == this) { | 3304 if (isolate->initial_object_prototype()->map() == this) { |
3299 return true; | 3305 return true; |
3300 } | 3306 } |
3301 | 3307 |
3302 return false; | 3308 return false; |
3303 } | 3309 } |
3304 | 3310 |
3305 | 3311 |
3306 static MaybeObject* AddMissingElementsTransitions(Map* map, | 3312 static MaybeObject* AddMissingElementsTransitions(Map* map, |
3307 ElementsKind to_kind) { | 3313 ElementsKind to_kind) { |
3308 ASSERT(IsFastElementsKind(map->elements_kind())); | 3314 ASSERT(IsTransitionElementsKind(map->elements_kind())); |
3309 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()); | |
3310 int to_index = IsFastElementsKind(to_kind) | |
3311 ? GetSequenceIndexFromFastElementsKind(to_kind) | |
3312 : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND); | |
3313 | |
3314 ASSERT(index <= to_index); | |
3315 | 3315 |
3316 Map* current_map = map; | 3316 Map* current_map = map; |
3317 | 3317 |
3318 for (; index < to_index; ++index) { | 3318 ElementsKind kind = map->elements_kind(); |
3319 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index + 1); | 3319 while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
3320 kind = GetNextTransitionElementsKind(kind); | |
3320 MaybeObject* maybe_next_map = | 3321 MaybeObject* maybe_next_map = |
3321 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); | 3322 current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); |
3322 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3323 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
3323 } | 3324 } |
3324 | 3325 |
3325 // In case we are exiting the fast elements kind system, just add the map in | 3326 // In case we are exiting the fast elements kind system, just add the map in |
3326 // the end. | 3327 // the end. |
3327 if (!IsFastElementsKind(to_kind)) { | 3328 if (kind != to_kind) { |
3328 MaybeObject* maybe_next_map = | 3329 MaybeObject* maybe_next_map = |
3329 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); | 3330 current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); |
3330 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; | 3331 if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
3331 } | 3332 } |
3332 | 3333 |
3333 ASSERT(current_map->elements_kind() == to_kind); | 3334 ASSERT(current_map->elements_kind() == to_kind); |
3334 return current_map; | 3335 return current_map; |
3335 } | 3336 } |
3336 | 3337 |
3337 | 3338 |
(...skipping 11 matching lines...) Expand all Loading... | |
3349 ElementsKind from_kind = start_map->elements_kind(); | 3350 ElementsKind from_kind = start_map->elements_kind(); |
3350 | 3351 |
3351 if (from_kind == to_kind) { | 3352 if (from_kind == to_kind) { |
3352 return start_map; | 3353 return start_map; |
3353 } | 3354 } |
3354 | 3355 |
3355 bool allow_store_transition = | 3356 bool allow_store_transition = |
3356 // Only remember the map transition if there is not an already existing | 3357 // Only remember the map transition if there is not an already existing |
3357 // non-matching element transition. | 3358 // non-matching element transition. |
3358 !start_map->IsUndefined() && !start_map->is_shared() && | 3359 !start_map->IsUndefined() && !start_map->is_shared() && |
3359 IsFastElementsKind(from_kind); | 3360 IsTransitionElementsKind(from_kind); |
3360 | 3361 |
3361 // Only store fast element maps in ascending generality. | 3362 // Only store fast element maps in ascending generality. |
3362 if (IsFastElementsKind(to_kind)) { | 3363 if (IsFastElementsKind(to_kind)) { |
3363 allow_store_transition &= | 3364 allow_store_transition &= |
3364 IsTransitionableFastElementsKind(from_kind) && | 3365 IsTransitionableFastElementsKind(from_kind) && |
3365 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 3366 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
3366 } | 3367 } |
3367 | 3368 |
3368 if (!allow_store_transition) { | 3369 if (!allow_store_transition) { |
3369 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); | 3370 return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); |
3370 } | 3371 } |
3371 | 3372 |
3372 return start_map->AsElementsKind(to_kind); | 3373 return start_map->AsElementsKind(to_kind); |
3373 } | 3374 } |
3374 | 3375 |
3375 | 3376 |
3376 MaybeObject* Map::AsElementsKind(ElementsKind kind) { | 3377 MaybeObject* Map::AsElementsKind(ElementsKind kind) { |
3377 Map* closest_map = FindClosestElementsTransition(this, kind); | 3378 Map* closest_map = FindClosestElementsTransition(this, kind); |
3378 | 3379 |
3379 if (closest_map->elements_kind() == kind) { | 3380 if (closest_map->elements_kind() == kind) { |
3380 return closest_map; | 3381 return closest_map; |
3381 } | 3382 } |
3382 | 3383 |
3383 return AddMissingElementsTransitions(closest_map, kind); | 3384 return AddMissingElementsTransitions(closest_map, kind); |
3384 } | 3385 } |
3385 | 3386 |
3386 | 3387 |
3388 Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { | |
3389 CALL_HEAP_FUNCTION(map->GetIsolate(), map->AsElementsKind(kind), Map); | |
3390 } | |
3391 | |
3392 | |
3387 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { | 3393 void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) { |
3388 if (IsJSGlobalProxy()) { | 3394 if (IsJSGlobalProxy()) { |
3389 Object* proto = GetPrototype(); | 3395 Object* proto = GetPrototype(); |
3390 if (proto->IsNull()) return result->NotFound(); | 3396 if (proto->IsNull()) return result->NotFound(); |
3391 ASSERT(proto->IsJSGlobalObject()); | 3397 ASSERT(proto->IsJSGlobalObject()); |
3392 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); | 3398 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); |
3393 } | 3399 } |
3394 | 3400 |
3395 if (HasFastProperties()) { | 3401 if (HasFastProperties()) { |
3396 map()->LookupDescriptor(this, name, result); | 3402 map()->LookupDescriptor(this, name, result); |
(...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4727 | 4733 |
4728 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4734 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
4729 Handle<JSObject> object) { | 4735 Handle<JSObject> object) { |
4730 CALL_HEAP_FUNCTION(object->GetIsolate(), | 4736 CALL_HEAP_FUNCTION(object->GetIsolate(), |
4731 object->NormalizeElements(), | 4737 object->NormalizeElements(), |
4732 SeededNumberDictionary); | 4738 SeededNumberDictionary); |
4733 } | 4739 } |
4734 | 4740 |
4735 | 4741 |
4736 MaybeObject* JSObject::NormalizeElements() { | 4742 MaybeObject* JSObject::NormalizeElements() { |
4737 ASSERT(!HasExternalArrayElements()); | 4743 ASSERT(!HasExternalArrayElements() && !HasFixedTypedArrayElements()); |
4738 | 4744 |
4739 // Find the backing store. | 4745 // Find the backing store. |
4740 FixedArrayBase* array = FixedArrayBase::cast(elements()); | 4746 FixedArrayBase* array = FixedArrayBase::cast(elements()); |
4741 Map* old_map = array->map(); | 4747 Map* old_map = array->map(); |
4742 bool is_arguments = | 4748 bool is_arguments = |
4743 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); | 4749 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); |
4744 if (is_arguments) { | 4750 if (is_arguments) { |
4745 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); | 4751 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); |
4746 } | 4752 } |
4747 if (array->IsDictionary()) return array; | 4753 if (array->IsDictionary()) return array; |
(...skipping 720 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 6959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12528 Handle<Object> proto(object->GetPrototype(), isolate); | 12536 Handle<Object> proto(object->GetPrototype(), isolate); |
12529 if (proto->IsNull()) return value; | 12537 if (proto->IsNull()) return value; |
12530 ASSERT(proto->IsJSGlobalObject()); | 12538 ASSERT(proto->IsJSGlobalObject()); |
12531 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, | 12539 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
12532 strict_mode, | 12540 strict_mode, |
12533 check_prototype, | 12541 check_prototype, |
12534 set_mode); | 12542 set_mode); |
12535 } | 12543 } |
12536 | 12544 |
12537 // Don't allow element properties to be redefined for external arrays. | 12545 // Don't allow element properties to be redefined for external arrays. |
12538 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 12546 if ((object->HasExternalArrayElements() || |
12547 object->HasFixedTypedArrayElements()) && | |
12548 set_mode == DEFINE_PROPERTY) { | |
12539 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12549 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12540 Handle<Object> args[] = { object, number }; | 12550 Handle<Object> args[] = { object, number }; |
12541 Handle<Object> error = isolate->factory()->NewTypeError( | 12551 Handle<Object> error = isolate->factory()->NewTypeError( |
12542 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12552 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
12543 isolate->Throw(*error); | 12553 isolate->Throw(*error); |
12544 return Handle<Object>(); | 12554 return Handle<Object>(); |
12545 } | 12555 } |
12546 | 12556 |
12547 // Normalize the elements to enable attributes on the property. | 12557 // Normalize the elements to enable attributes on the property. |
12548 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12558 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
(...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14449 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); | 14459 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); |
14450 | 14460 |
14451 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? | 14461 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? |
14452 NOT_TENURED: TENURED; | 14462 NOT_TENURED: TENURED; |
14453 Handle<FixedArray> fast_elements = | 14463 Handle<FixedArray> fast_elements = |
14454 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14464 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
14455 dict->CopyValuesTo(*fast_elements); | 14465 dict->CopyValuesTo(*fast_elements); |
14456 object->ValidateElements(); | 14466 object->ValidateElements(); |
14457 | 14467 |
14458 object->set_map_and_elements(*new_map, *fast_elements); | 14468 object->set_map_and_elements(*new_map, *fast_elements); |
14459 } else if (object->HasExternalArrayElements()) { | 14469 } else if (object->HasExternalArrayElements() || |
14460 // External arrays cannot have holes or undefined elements. | 14470 object->HasFixedTypedArrayElements()) { |
14471 // Typed arrays cannot have holes or undefined elements. | |
14461 return handle(Smi::FromInt( | 14472 return handle(Smi::FromInt( |
14462 ExternalArray::cast(object->elements())->length()), isolate); | 14473 FixedArrayBase::cast(object->elements())->length()), isolate); |
14463 } else if (!object->HasFastDoubleElements()) { | 14474 } else if (!object->HasFastDoubleElements()) { |
14464 EnsureWritableFastElements(object); | 14475 EnsureWritableFastElements(object); |
14465 } | 14476 } |
14466 ASSERT(object->HasFastSmiOrObjectElements() || | 14477 ASSERT(object->HasFastSmiOrObjectElements() || |
14467 object->HasFastDoubleElements()); | 14478 object->HasFastDoubleElements()); |
14468 | 14479 |
14469 // Collect holes at the end, undefined before that and the rest at the | 14480 // Collect holes at the end, undefined before that and the rest at the |
14470 // start, and return the number of non-hole, non-undefined values. | 14481 // start, and return the number of non-hole, non-undefined values. |
14471 | 14482 |
14472 Handle<FixedArrayBase> elements_base(object->elements()); | 14483 Handle<FixedArrayBase> elements_base(object->elements()); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14553 } | 14564 } |
14554 | 14565 |
14555 return isolate->factory()->NewNumberFromUint(result); | 14566 return isolate->factory()->NewNumberFromUint(result); |
14556 } | 14567 } |
14557 | 14568 |
14558 | 14569 |
14559 ExternalArrayType JSTypedArray::type() { | 14570 ExternalArrayType JSTypedArray::type() { |
14560 switch (elements()->map()->instance_type()) { | 14571 switch (elements()->map()->instance_type()) { |
14561 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ | 14572 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ |
14562 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14573 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
14574 case FIXED_##TYPE##_ARRAY_TYPE: \ | |
14563 return kExternal##Type##Array; | 14575 return kExternal##Type##Array; |
14564 | 14576 |
14565 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) | 14577 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) |
14566 #undef INSTANCE_TYPE_TO_ARRAY_TYPE | 14578 #undef INSTANCE_TYPE_TO_ARRAY_TYPE |
14567 | 14579 |
14568 default: | 14580 default: |
14581 UNREACHABLE(); | |
14569 return static_cast<ExternalArrayType>(-1); | 14582 return static_cast<ExternalArrayType>(-1); |
14570 } | 14583 } |
14571 } | 14584 } |
14572 | 14585 |
14573 | 14586 |
14574 size_t JSTypedArray::element_size() { | 14587 size_t JSTypedArray::element_size() { |
14575 switch (elements()->map()->instance_type()) { | 14588 switch (elements()->map()->instance_type()) { |
14576 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ | 14589 #define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size) \ |
14577 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 14590 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
14578 return size; | 14591 return size; |
(...skipping 1837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16416 } | 16429 } |
16417 | 16430 |
16418 | 16431 |
16419 void JSTypedArray::Neuter() { | 16432 void JSTypedArray::Neuter() { |
16420 NeuterView(); | 16433 NeuterView(); |
16421 set_length(Smi::FromInt(0)); | 16434 set_length(Smi::FromInt(0)); |
16422 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); | 16435 set_elements(GetHeap()->EmptyExternalArrayForMap(map())); |
16423 } | 16436 } |
16424 | 16437 |
16425 | 16438 |
16439 static ElementsKind FixedToExternalElementsKind(ElementsKind elements_kind) { | |
16440 switch (elements_kind) { | |
16441 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | |
16442 case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS; | |
16443 | |
16444 TYPED_ARRAYS(TYPED_ARRAY_CASE) | |
16445 #undef TYPED_ARRAY_CASE | |
16446 | |
16447 default: | |
16448 UNREACHABLE(); | |
16449 return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND; | |
16450 } | |
16451 } | |
16452 | |
16453 | |
16454 Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer( | |
16455 Handle<JSTypedArray> typed_array) { | |
16456 | |
16457 printf("Materializing buffer!\n"); | |
mvstanton
2014/03/03 10:37:49
Remove this printf().
Dmitry Lomov (no reviews)
2014/03/10 09:20:35
Done.
| |
16458 Handle<Map> map(typed_array->map()); | |
16459 Isolate* isolate = typed_array->GetIsolate(); | |
16460 | |
16461 ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind())); | |
16462 | |
16463 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | |
16464 Handle<FixedTypedArrayBase> fixed_typed_array( | |
16465 FixedTypedArrayBase::cast(typed_array->elements())); | |
16466 Runtime::SetupArrayBufferAllocatingData(isolate, buffer, | |
16467 fixed_typed_array->DataSize(), false); | |
16468 memcpy(buffer->backing_store(), | |
16469 fixed_typed_array->DataPtr(), | |
16470 fixed_typed_array->DataSize()); | |
16471 Handle<ExternalArray> new_elements = | |
16472 isolate->factory()->NewExternalArray( | |
16473 fixed_typed_array->length(), typed_array->type(), | |
16474 static_cast<uint8_t*>(buffer->backing_store())); | |
16475 Handle<Map> new_map = | |
16476 isolate->factory()->GetElementsTransitionMap( | |
16477 typed_array, | |
16478 FixedToExternalElementsKind(map->elements_kind())); | |
16479 | |
16480 buffer->set_weak_first_view(*typed_array); | |
16481 ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value()); | |
16482 typed_array->set_buffer(*buffer); | |
16483 typed_array->set_map_and_elements(*new_map, *new_elements); | |
16484 | |
16485 return buffer; | |
16486 } | |
16487 | |
16488 | |
16489 Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { | |
16490 Handle<Object> result(buffer(), GetIsolate()); | |
16491 if (*result != Smi::FromInt(0)) { | |
16492 ASSERT(IsExternalArrayElementsKind(map()->elements_kind())); | |
16493 return Handle<JSArrayBuffer>::cast(result); | |
16494 } | |
16495 Handle<JSTypedArray> self(this); | |
16496 return MaterializeArrayBuffer(self); | |
16497 } | |
16498 | |
16499 | |
16426 HeapType* PropertyCell::type() { | 16500 HeapType* PropertyCell::type() { |
16427 return static_cast<HeapType*>(type_raw()); | 16501 return static_cast<HeapType*>(type_raw()); |
16428 } | 16502 } |
16429 | 16503 |
16430 | 16504 |
16431 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { | 16505 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { |
16432 ASSERT(IsPropertyCell()); | 16506 ASSERT(IsPropertyCell()); |
16433 set_type_raw(type, ignored); | 16507 set_type_raw(type, ignored); |
16434 } | 16508 } |
16435 | 16509 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16484 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16558 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16485 static const char* error_messages_[] = { | 16559 static const char* error_messages_[] = { |
16486 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16560 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16487 }; | 16561 }; |
16488 #undef ERROR_MESSAGES_TEXTS | 16562 #undef ERROR_MESSAGES_TEXTS |
16489 return error_messages_[reason]; | 16563 return error_messages_[reason]; |
16490 } | 16564 } |
16491 | 16565 |
16492 | 16566 |
16493 } } // namespace v8::internal | 16567 } } // namespace v8::internal |
OLD | NEW |