OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 13423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13434 ASSERT(args.length() == 1); | 13434 ASSERT(args.length() == 1); |
13435 Object* object = args[0]; | 13435 Object* object = args[0]; |
13436 if (object->IsJSGlobalProxy()) { | 13436 if (object->IsJSGlobalProxy()) { |
13437 object = object->GetPrototype(isolate); | 13437 object = object->GetPrototype(isolate); |
13438 if (object->IsNull()) return isolate->heap()->undefined_value(); | 13438 if (object->IsNull()) return isolate->heap()->undefined_value(); |
13439 } | 13439 } |
13440 return object; | 13440 return object; |
13441 } | 13441 } |
13442 | 13442 |
13443 | 13443 |
| 13444 static MaybeObject* ArrayConstructorCommon(Isolate* isolate, |
| 13445 Handle<JSFunction> constructor, |
| 13446 Handle<Object> type_info, |
| 13447 Arguments* caller_args) { |
| 13448 bool holey = false; |
| 13449 bool can_use_type_feedback = true; |
| 13450 if (caller_args->length() == 1) { |
| 13451 Object* argument_one = (*caller_args)[0]; |
| 13452 if (argument_one->IsSmi()) { |
| 13453 int value = Smi::cast(argument_one)->value(); |
| 13454 if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) { |
| 13455 // the array is a dictionary in this case. |
| 13456 can_use_type_feedback = false; |
| 13457 } else if (value != 0) { |
| 13458 holey = true; |
| 13459 } |
| 13460 } else { |
| 13461 // Non-smi length argument produces a dictionary |
| 13462 can_use_type_feedback = false; |
| 13463 } |
| 13464 } |
| 13465 |
| 13466 JSArray* array; |
| 13467 MaybeObject* maybe_array; |
| 13468 if (!type_info.is_null() && |
| 13469 *type_info != isolate->heap()->undefined_value() && |
| 13470 JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi() && |
| 13471 can_use_type_feedback) { |
| 13472 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info); |
| 13473 Smi* smi = Smi::cast(cell->value()); |
| 13474 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); |
| 13475 if (holey && !IsFastHoleyElementsKind(to_kind)) { |
| 13476 to_kind = GetHoleyElementsKind(to_kind); |
| 13477 // Update the allocation site info to reflect the advice alteration. |
| 13478 cell->set_value(Smi::FromInt(to_kind)); |
| 13479 } |
| 13480 |
| 13481 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( |
| 13482 *constructor, type_info); |
| 13483 if (!maybe_array->To(&array)) return maybe_array; |
| 13484 } else { |
| 13485 maybe_array = isolate->heap()->AllocateJSObject(*constructor); |
| 13486 if (!maybe_array->To(&array)) return maybe_array; |
| 13487 // We might need to transition to holey |
| 13488 ElementsKind kind = constructor->initial_map()->elements_kind(); |
| 13489 if (holey && !IsFastHoleyElementsKind(kind)) { |
| 13490 kind = GetHoleyElementsKind(kind); |
| 13491 maybe_array = array->TransitionElementsKind(kind); |
| 13492 if (maybe_array->IsFailure()) return maybe_array; |
| 13493 } |
| 13494 } |
| 13495 |
| 13496 maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0, |
| 13497 DONT_INITIALIZE_ARRAY_ELEMENTS); |
| 13498 if (maybe_array->IsFailure()) return maybe_array; |
| 13499 maybe_array = ArrayConstructInitializeElements(array, caller_args); |
| 13500 if (maybe_array->IsFailure()) return maybe_array; |
| 13501 return array; |
| 13502 } |
| 13503 |
| 13504 |
| 13505 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) { |
| 13506 HandleScope scope(isolate); |
| 13507 // If we get 2 arguments then they are the stub parameters (constructor, type |
| 13508 // info). If we get 3, then the first one is a pointer to the arguments |
| 13509 // passed by the caller. |
| 13510 Arguments empty_args(0, NULL); |
| 13511 bool no_caller_args = args.length() == 2; |
| 13512 ASSERT(no_caller_args || args.length() == 3); |
| 13513 int parameters_start = no_caller_args ? 0 : 1; |
| 13514 Arguments* caller_args = no_caller_args |
| 13515 ? &empty_args |
| 13516 : reinterpret_cast<Arguments*>(args[0]); |
| 13517 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); |
| 13518 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1); |
| 13519 |
| 13520 return ArrayConstructorCommon(isolate, |
| 13521 constructor, |
| 13522 type_info, |
| 13523 caller_args); |
| 13524 } |
| 13525 |
| 13526 |
| 13527 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) { |
| 13528 HandleScope scope(isolate); |
| 13529 Arguments empty_args(0, NULL); |
| 13530 bool no_caller_args = args.length() == 1; |
| 13531 ASSERT(no_caller_args || args.length() == 2); |
| 13532 int parameters_start = no_caller_args ? 0 : 1; |
| 13533 Arguments* caller_args = no_caller_args |
| 13534 ? &empty_args |
| 13535 : reinterpret_cast<Arguments*>(args[0]); |
| 13536 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); |
| 13537 |
| 13538 return ArrayConstructorCommon(isolate, |
| 13539 constructor, |
| 13540 Handle<Object>::null(), |
| 13541 caller_args); |
| 13542 } |
| 13543 |
| 13544 |
13444 // ---------------------------------------------------------------------------- | 13545 // ---------------------------------------------------------------------------- |
13445 // Implementation of Runtime | 13546 // Implementation of Runtime |
13446 | 13547 |
13447 #define F(name, number_of_args, result_size) \ | 13548 #define F(name, number_of_args, result_size) \ |
13448 { Runtime::k##name, Runtime::RUNTIME, #name, \ | 13549 { Runtime::k##name, Runtime::RUNTIME, #name, \ |
13449 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, | 13550 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, |
13450 | 13551 |
13451 | 13552 |
13452 #define I(name, number_of_args, result_size) \ | 13553 #define I(name, number_of_args, result_size) \ |
13453 { Runtime::kInline##name, Runtime::INLINE, \ | 13554 { Runtime::kInline##name, Runtime::INLINE, \ |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13520 // Handle last resort GC and make sure to allow future allocations | 13621 // Handle last resort GC and make sure to allow future allocations |
13521 // to grow the heap without causing GCs (if possible). | 13622 // to grow the heap without causing GCs (if possible). |
13522 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13623 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13523 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13624 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13524 "Runtime::PerformGC"); | 13625 "Runtime::PerformGC"); |
13525 } | 13626 } |
13526 } | 13627 } |
13527 | 13628 |
13528 | 13629 |
13529 } } // namespace v8::internal | 13630 } } // namespace v8::internal |
OLD | NEW |