Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/objects.cc

Issue 150813004: In-heap small typed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: CR feedback + rebase Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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(&current_map)) return maybe_next_map; 3319 if (!maybe_next_map->To(&current_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(&current_map)) return maybe_next_map; 3327 if (!maybe_next_map->To(&current_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
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
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
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
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
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
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
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
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
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
OLDNEW
« src/hydrogen.cc ('K') | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698