| 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 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 Handle<Object> name(args[0], isolate); | 581 Handle<Object> name(args[0], isolate); |
| 582 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); | 582 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); |
| 583 Symbol* symbol; | 583 Symbol* symbol; |
| 584 MaybeObject* maybe = isolate->heap()->AllocateSymbol(); | 584 MaybeObject* maybe = isolate->heap()->AllocateSymbol(); |
| 585 if (!maybe->To(&symbol)) return maybe; | 585 if (!maybe->To(&symbol)) return maybe; |
| 586 if (name->IsString()) symbol->set_name(*name); | 586 if (name->IsString()) symbol->set_name(*name); |
| 587 return symbol; | 587 return symbol; |
| 588 } | 588 } |
| 589 | 589 |
| 590 | 590 |
| 591 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreatePrivateSymbol) { |
| 592 HandleScope scope(isolate); |
| 593 ASSERT(args.length() == 1); |
| 594 Handle<Object> name(args[0], isolate); |
| 595 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); |
| 596 Symbol* symbol; |
| 597 MaybeObject* maybe = isolate->heap()->AllocatePrivateSymbol(); |
| 598 if (!maybe->To(&symbol)) return maybe; |
| 599 if (name->IsString()) symbol->set_name(*name); |
| 600 return symbol; |
| 601 } |
| 602 |
| 603 |
| 591 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolName) { | 604 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolName) { |
| 592 SealHandleScope shs(isolate); | 605 SealHandleScope shs(isolate); |
| 593 ASSERT(args.length() == 1); | 606 ASSERT(args.length() == 1); |
| 594 CONVERT_ARG_CHECKED(Symbol, symbol, 0); | 607 CONVERT_ARG_CHECKED(Symbol, symbol, 0); |
| 595 return symbol->name(); | 608 return symbol->name(); |
| 596 } | 609 } |
| 597 | 610 |
| 598 | 611 |
| 612 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolIsPrivate) { |
| 613 SealHandleScope shs(isolate); |
| 614 ASSERT(args.length() == 1); |
| 615 CONVERT_ARG_CHECKED(Symbol, symbol, 0); |
| 616 return isolate->heap()->ToBoolean(symbol->is_private()); |
| 617 } |
| 618 |
| 619 |
| 599 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) { | 620 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) { |
| 600 SealHandleScope shs(isolate); | 621 SealHandleScope shs(isolate); |
| 601 ASSERT(args.length() == 2); | 622 ASSERT(args.length() == 2); |
| 602 CONVERT_ARG_CHECKED(JSReceiver, handler, 0); | 623 CONVERT_ARG_CHECKED(JSReceiver, handler, 0); |
| 603 Object* prototype = args[1]; | 624 Object* prototype = args[1]; |
| 604 Object* used_prototype = | 625 Object* used_prototype = |
| 605 prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value(); | 626 prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value(); |
| 606 return isolate->heap()->AllocateJSProxy(handler, used_prototype); | 627 return isolate->heap()->AllocateJSProxy(handler, used_prototype); |
| 607 } | 628 } |
| 608 | 629 |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 | 910 |
| 890 holder->set_buffer(*buffer); | 911 holder->set_buffer(*buffer); |
| 891 holder->set_byte_offset(*byte_offset_object); | 912 holder->set_byte_offset(*byte_offset_object); |
| 892 holder->set_byte_length(*byte_length_object); | 913 holder->set_byte_length(*byte_length_object); |
| 893 | 914 |
| 894 size_t byte_offset = NumberToSize(isolate, *byte_offset_object); | 915 size_t byte_offset = NumberToSize(isolate, *byte_offset_object); |
| 895 size_t byte_length = NumberToSize(isolate, *byte_length_object); | 916 size_t byte_length = NumberToSize(isolate, *byte_length_object); |
| 896 ASSERT(byte_length % element_size == 0); | 917 ASSERT(byte_length % element_size == 0); |
| 897 size_t length = byte_length / element_size; | 918 size_t length = byte_length / element_size; |
| 898 | 919 |
| 920 if (length > static_cast<unsigned>(Smi::kMaxValue)) { |
| 921 return isolate->Throw(*isolate->factory()-> |
| 922 NewRangeError("invalid_typed_array_length", |
| 923 HandleVector<Object>(NULL, 0))); |
| 924 } |
| 925 |
| 899 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); | 926 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); |
| 900 holder->set_length(*length_obj); | 927 holder->set_length(*length_obj); |
| 901 holder->set_weak_next(buffer->weak_first_view()); | 928 holder->set_weak_next(buffer->weak_first_view()); |
| 902 buffer->set_weak_first_view(*holder); | 929 buffer->set_weak_first_view(*holder); |
| 903 | 930 |
| 904 Handle<ExternalArray> elements = | 931 Handle<ExternalArray> elements = |
| 905 isolate->factory()->NewExternalArray( | 932 isolate->factory()->NewExternalArray( |
| 906 static_cast<int>(length), array_type, | 933 static_cast<int>(length), array_type, |
| 907 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); | 934 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); |
| 908 holder->set_elements(*elements); | 935 holder->set_elements(*elements); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 928 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { | 955 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
| 929 holder->SetInternalField(i, Smi::FromInt(0)); | 956 holder->SetInternalField(i, Smi::FromInt(0)); |
| 930 } | 957 } |
| 931 | 958 |
| 932 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. | 959 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. |
| 933 size_t element_size = 1; // Bogus initialization. | 960 size_t element_size = 1; // Bogus initialization. |
| 934 ArrayIdToTypeAndSize(arrayId, &array_type, &element_size); | 961 ArrayIdToTypeAndSize(arrayId, &array_type, &element_size); |
| 935 | 962 |
| 936 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | 963 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
| 937 size_t length = NumberToSize(isolate, *length_obj); | 964 size_t length = NumberToSize(isolate, *length_obj); |
| 938 size_t byte_length = length * element_size; | 965 |
| 939 if (byte_length < length) { // Overflow | 966 if ((length > static_cast<unsigned>(Smi::kMaxValue)) || |
| 967 (length > (kMaxInt / element_size))) { |
| 940 return isolate->Throw(*isolate->factory()-> | 968 return isolate->Throw(*isolate->factory()-> |
| 941 NewRangeError("invalid_array_buffer_length", | 969 NewRangeError("invalid_typed_array_length", |
| 942 HandleVector<Object>(NULL, 0))); | 970 HandleVector<Object>(NULL, 0))); |
| 943 } | 971 } |
| 972 size_t byte_length = length * element_size; |
| 944 | 973 |
| 945 // NOTE: not initializing backing store. | 974 // NOTE: not initializing backing store. |
| 946 // We assume that the caller of this function will initialize holder | 975 // We assume that the caller of this function will initialize holder |
| 947 // with the loop | 976 // with the loop |
| 948 // for(i = 0; i < length; i++) { holder[i] = source[i]; } | 977 // for(i = 0; i < length; i++) { holder[i] = source[i]; } |
| 949 // We assume that the caller of this function is always a typed array | 978 // We assume that the caller of this function is always a typed array |
| 950 // constructor. | 979 // constructor. |
| 951 // If source is a typed array, this loop will always run to completion, | 980 // If source is a typed array, this loop will always run to completion, |
| 952 // so we are sure that the backing store will be initialized. | 981 // so we are sure that the backing store will be initialized. |
| 953 // Otherwise, the indexing operation might throw, so the loop will not | 982 // Otherwise, the indexing operation might throw, so the loop will not |
| (...skipping 3829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4783 } | 4812 } |
| 4784 | 4813 |
| 4785 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { | 4814 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
| 4786 return object->GetPrototype(isolate)->GetElement(isolate, index); | 4815 return object->GetPrototype(isolate)->GetElement(isolate, index); |
| 4787 } | 4816 } |
| 4788 | 4817 |
| 4789 return object->GetElement(isolate, index); | 4818 return object->GetElement(isolate, index); |
| 4790 } | 4819 } |
| 4791 | 4820 |
| 4792 | 4821 |
| 4822 static Handle<Name> ToName(Isolate* isolate, Handle<Object> key) { |
| 4823 if (key->IsName()) { |
| 4824 return Handle<Name>::cast(key); |
| 4825 } else { |
| 4826 bool has_pending_exception = false; |
| 4827 Handle<Object> converted = |
| 4828 Execution::ToString(isolate, key, &has_pending_exception); |
| 4829 if (has_pending_exception) return Handle<Name>(); |
| 4830 return Handle<Name>::cast(converted); |
| 4831 } |
| 4832 } |
| 4833 |
| 4834 |
| 4793 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate, | 4835 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate, |
| 4794 Handle<JSReceiver> object, | 4836 Handle<JSReceiver> object, |
| 4795 Handle<Object> key) { | 4837 Handle<Object> key) { |
| 4796 HandleScope scope(isolate); | 4838 HandleScope scope(isolate); |
| 4797 | 4839 |
| 4798 // Check if the given key is an array index. | 4840 // Check if the given key is an array index. |
| 4799 uint32_t index; | 4841 uint32_t index; |
| 4800 if (key->ToArrayIndex(&index)) { | 4842 if (key->ToArrayIndex(&index)) { |
| 4801 return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index)); | 4843 return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index)); |
| 4802 } | 4844 } |
| 4803 | 4845 |
| 4804 // Convert the key to a name - possibly by calling back into JavaScript. | 4846 // Convert the key to a name - possibly by calling back into JavaScript. |
| 4805 Handle<Name> name; | 4847 Handle<Name> name = ToName(isolate, key); |
| 4806 if (key->IsName()) { | 4848 RETURN_IF_EMPTY_HANDLE(isolate, name); |
| 4807 name = Handle<Name>::cast(key); | |
| 4808 } else { | |
| 4809 bool has_pending_exception = false; | |
| 4810 Handle<Object> converted = | |
| 4811 Execution::ToString(isolate, key, &has_pending_exception); | |
| 4812 if (has_pending_exception) return Failure::Exception(); | |
| 4813 name = Handle<Name>::cast(converted); | |
| 4814 } | |
| 4815 | 4849 |
| 4816 return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name)); | 4850 return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name)); |
| 4817 } | 4851 } |
| 4818 | 4852 |
| 4819 MaybeObject* Runtime::GetObjectPropertyOrFail( | 4853 MaybeObject* Runtime::GetObjectPropertyOrFail( |
| 4820 Isolate* isolate, | 4854 Isolate* isolate, |
| 4821 Handle<Object> object, | 4855 Handle<Object> object, |
| 4822 Handle<Object> key) { | 4856 Handle<Object> key) { |
| 4823 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, | 4857 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, |
| 4824 GetObjectProperty(isolate, object, key)); | 4858 GetObjectProperty(isolate, object, key)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4837 return isolate->Throw(*error); | 4871 return isolate->Throw(*error); |
| 4838 } | 4872 } |
| 4839 | 4873 |
| 4840 // Check if the given key is an array index. | 4874 // Check if the given key is an array index. |
| 4841 uint32_t index; | 4875 uint32_t index; |
| 4842 if (key->ToArrayIndex(&index)) { | 4876 if (key->ToArrayIndex(&index)) { |
| 4843 return GetElementOrCharAt(isolate, object, index); | 4877 return GetElementOrCharAt(isolate, object, index); |
| 4844 } | 4878 } |
| 4845 | 4879 |
| 4846 // Convert the key to a name - possibly by calling back into JavaScript. | 4880 // Convert the key to a name - possibly by calling back into JavaScript. |
| 4847 Handle<Name> name; | 4881 Handle<Name> name = ToName(isolate, key); |
| 4848 if (key->IsName()) { | 4882 RETURN_IF_EMPTY_HANDLE(isolate, name); |
| 4849 name = Handle<Name>::cast(key); | |
| 4850 } else { | |
| 4851 bool has_pending_exception = false; | |
| 4852 Handle<Object> converted = | |
| 4853 Execution::ToString(isolate, key, &has_pending_exception); | |
| 4854 if (has_pending_exception) return Failure::Exception(); | |
| 4855 name = Handle<Name>::cast(converted); | |
| 4856 } | |
| 4857 | 4883 |
| 4858 // Check if the name is trivially convertible to an index and get | 4884 // Check if the name is trivially convertible to an index and get |
| 4859 // the element if so. | 4885 // the element if so. |
| 4860 if (name->AsArrayIndex(&index)) { | 4886 if (name->AsArrayIndex(&index)) { |
| 4861 return GetElementOrCharAt(isolate, object, index); | 4887 return GetElementOrCharAt(isolate, object, index); |
| 4862 } else { | 4888 } else { |
| 4863 return object->GetProperty(*name); | 4889 return object->GetProperty(*name); |
| 4864 } | 4890 } |
| 4865 } | 4891 } |
| 4866 | 4892 |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5372 CONVERT_ARG_CHECKED(Object, object, 0); | 5398 CONVERT_ARG_CHECKED(Object, object, 0); |
| 5373 | 5399 |
| 5374 if (object->IsJSFunction()) { | 5400 if (object->IsJSFunction()) { |
| 5375 JSFunction* func = JSFunction::cast(object); | 5401 JSFunction* func = JSFunction::cast(object); |
| 5376 func->shared()->set_native(true); | 5402 func->shared()->set_native(true); |
| 5377 } | 5403 } |
| 5378 return isolate->heap()->undefined_value(); | 5404 return isolate->heap()->undefined_value(); |
| 5379 } | 5405 } |
| 5380 | 5406 |
| 5381 | 5407 |
| 5408 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInlineBuiltinFlag) { |
| 5409 SealHandleScope shs(isolate); |
| 5410 RUNTIME_ASSERT(args.length() == 1); |
| 5411 |
| 5412 Handle<Object> object = args.at<Object>(0); |
| 5413 |
| 5414 if (object->IsJSFunction()) { |
| 5415 JSFunction* func = JSFunction::cast(*object); |
| 5416 func->shared()->set_inline_builtin(true); |
| 5417 } |
| 5418 return isolate->heap()->undefined_value(); |
| 5419 } |
| 5420 |
| 5421 |
| 5382 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { | 5422 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { |
| 5383 HandleScope scope(isolate); | 5423 HandleScope scope(isolate); |
| 5384 RUNTIME_ASSERT(args.length() == 5); | 5424 RUNTIME_ASSERT(args.length() == 5); |
| 5385 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 5425 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
| 5386 CONVERT_SMI_ARG_CHECKED(store_index, 1); | 5426 CONVERT_SMI_ARG_CHECKED(store_index, 1); |
| 5387 Handle<Object> value = args.at<Object>(2); | 5427 Handle<Object> value = args.at<Object>(2); |
| 5388 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); | 5428 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); |
| 5389 CONVERT_SMI_ARG_CHECKED(literal_index, 4); | 5429 CONVERT_SMI_ARG_CHECKED(literal_index, 4); |
| 5390 | 5430 |
| 5391 Object* raw_literal_cell = literals->get(literal_index); | 5431 Object* raw_literal_cell = literals->get(literal_index); |
| (...skipping 2403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7795 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) { | 7835 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) { |
| 7796 SealHandleScope shs(isolate); | 7836 SealHandleScope shs(isolate); |
| 7797 ASSERT(args.length() == 1); | 7837 ASSERT(args.length() == 1); |
| 7798 isolate->counters()->math_tan()->Increment(); | 7838 isolate->counters()->math_tan()->Increment(); |
| 7799 | 7839 |
| 7800 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 7840 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
| 7801 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x); | 7841 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x); |
| 7802 } | 7842 } |
| 7803 | 7843 |
| 7804 | 7844 |
| 7845 RUNTIME_FUNCTION(MaybeObject*, Runtime_PopulateTrigonometricTable) { |
| 7846 HandleScope scope(isolate); |
| 7847 ASSERT(args.length() == 3); |
| 7848 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sin_table, 0); |
| 7849 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, cos_table, 1); |
| 7850 CONVERT_SMI_ARG_CHECKED(samples, 2); |
| 7851 RUNTIME_ASSERT(sin_table->type() == kExternalDoubleArray); |
| 7852 RUNTIME_ASSERT(cos_table->type() == kExternalDoubleArray); |
| 7853 double* sin_buffer = reinterpret_cast<double*>( |
| 7854 JSArrayBuffer::cast(sin_table->buffer())->backing_store()); |
| 7855 double* cos_buffer = reinterpret_cast<double*>( |
| 7856 JSArrayBuffer::cast(cos_table->buffer())->backing_store()); |
| 7857 |
| 7858 static const double pi_half = 3.1415926535897932 / 2; |
| 7859 double interval = pi_half / samples; |
| 7860 for (int i = 0; i < samples + 1; i++) { |
| 7861 double sample = sin(i * interval); |
| 7862 sin_buffer[i] = sample; |
| 7863 cos_buffer[samples - i] = sample * interval; |
| 7864 } |
| 7865 |
| 7866 // Fill this to catch out of bound accesses when calculating Math.sin(pi/2). |
| 7867 sin_buffer[samples + 1] = sin(pi_half + interval); |
| 7868 cos_buffer[samples + 1] = cos(pi_half + interval) * interval; |
| 7869 |
| 7870 return isolate->heap()->undefined_value(); |
| 7871 } |
| 7872 |
| 7873 |
| 7805 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) { | 7874 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) { |
| 7806 SealHandleScope shs(isolate); | 7875 SealHandleScope shs(isolate); |
| 7807 ASSERT(args.length() == 2); | 7876 ASSERT(args.length() == 2); |
| 7808 | 7877 |
| 7809 CONVERT_SMI_ARG_CHECKED(year, 0); | 7878 CONVERT_SMI_ARG_CHECKED(year, 0); |
| 7810 CONVERT_SMI_ARG_CHECKED(month, 1); | 7879 CONVERT_SMI_ARG_CHECKED(month, 1); |
| 7811 | 7880 |
| 7812 return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month)); | 7881 return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month)); |
| 7813 } | 7882 } |
| 7814 | 7883 |
| (...skipping 1892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9707 args.at<Object>(2), | 9776 args.at<Object>(2), |
| 9708 language_mode, | 9777 language_mode, |
| 9709 args.smi_at(4)); | 9778 args.smi_at(4)); |
| 9710 } | 9779 } |
| 9711 | 9780 |
| 9712 | 9781 |
| 9713 // Allocate a block of memory in the given space (filled with a filler). | 9782 // Allocate a block of memory in the given space (filled with a filler). |
| 9714 // Used as a fall-back for generated code when the space is full. | 9783 // Used as a fall-back for generated code when the space is full. |
| 9715 static MaybeObject* Allocate(Isolate* isolate, | 9784 static MaybeObject* Allocate(Isolate* isolate, |
| 9716 int size, | 9785 int size, |
| 9786 bool double_align, |
| 9717 AllocationSpace space) { | 9787 AllocationSpace space) { |
| 9718 Heap* heap = isolate->heap(); | 9788 Heap* heap = isolate->heap(); |
| 9719 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); | 9789 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); |
| 9720 RUNTIME_ASSERT(size > 0); | 9790 RUNTIME_ASSERT(size > 0); |
| 9721 RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize()); | 9791 RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize()); |
| 9722 HeapObject* allocation; | 9792 HeapObject* allocation; |
| 9723 { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space); | 9793 { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space); |
| 9724 if (!maybe_allocation->To(&allocation)) return maybe_allocation; | 9794 if (!maybe_allocation->To(&allocation)) return maybe_allocation; |
| 9725 } | 9795 } |
| 9726 #ifdef DEBUG | 9796 #ifdef DEBUG |
| 9727 MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address()); | 9797 MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address()); |
| 9728 ASSERT(chunk->owner()->identity() == space); | 9798 ASSERT(chunk->owner()->identity() == space); |
| 9729 #endif | 9799 #endif |
| 9730 heap->CreateFillerObjectAt(allocation->address(), size); | 9800 heap->CreateFillerObjectAt(allocation->address(), size); |
| 9731 return allocation; | 9801 return allocation; |
| 9732 } | 9802 } |
| 9733 | 9803 |
| 9734 | 9804 |
| 9735 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) { | 9805 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) { |
| 9736 SealHandleScope shs(isolate); | 9806 SealHandleScope shs(isolate); |
| 9737 ASSERT(args.length() == 1); | 9807 ASSERT(args.length() == 1); |
| 9738 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0); | 9808 CONVERT_SMI_ARG_CHECKED(size, 0); |
| 9739 return Allocate(isolate, size_smi->value(), NEW_SPACE); | 9809 return Allocate(isolate, size, false, NEW_SPACE); |
| 9740 } | 9810 } |
| 9741 | 9811 |
| 9742 | 9812 |
| 9743 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldPointerSpace) { | 9813 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInTargetSpace) { |
| 9744 SealHandleScope shs(isolate); | 9814 SealHandleScope shs(isolate); |
| 9745 ASSERT(args.length() == 1); | 9815 ASSERT(args.length() == 2); |
| 9746 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0); | 9816 CONVERT_SMI_ARG_CHECKED(size, 0); |
| 9747 return Allocate(isolate, size_smi->value(), OLD_POINTER_SPACE); | 9817 CONVERT_SMI_ARG_CHECKED(flags, 1); |
| 9818 bool double_align = AllocateDoubleAlignFlag::decode(flags); |
| 9819 AllocationSpace space = AllocateTargetSpace::decode(flags); |
| 9820 return Allocate(isolate, size, double_align, space); |
| 9748 } | 9821 } |
| 9749 | 9822 |
| 9750 | 9823 |
| 9751 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldDataSpace) { | |
| 9752 SealHandleScope shs(isolate); | |
| 9753 ASSERT(args.length() == 1); | |
| 9754 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0); | |
| 9755 return Allocate(isolate, size_smi->value(), OLD_DATA_SPACE); | |
| 9756 } | |
| 9757 | |
| 9758 | |
| 9759 // Push an object unto an array of objects if it is not already in the | 9824 // Push an object unto an array of objects if it is not already in the |
| 9760 // array. Returns true if the element was pushed on the stack and | 9825 // array. Returns true if the element was pushed on the stack and |
| 9761 // false otherwise. | 9826 // false otherwise. |
| 9762 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { | 9827 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { |
| 9763 SealHandleScope shs(isolate); | 9828 HandleScope scope(isolate); |
| 9764 ASSERT(args.length() == 2); | 9829 ASSERT(args.length() == 2); |
| 9765 CONVERT_ARG_CHECKED(JSArray, array, 0); | 9830 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |
| 9766 CONVERT_ARG_CHECKED(JSReceiver, element, 1); | 9831 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1); |
| 9767 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements()); | 9832 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements()); |
| 9768 int length = Smi::cast(array->length())->value(); | 9833 int length = Smi::cast(array->length())->value(); |
| 9769 FixedArray* elements = FixedArray::cast(array->elements()); | 9834 FixedArray* elements = FixedArray::cast(array->elements()); |
| 9770 for (int i = 0; i < length; i++) { | 9835 for (int i = 0; i < length; i++) { |
| 9771 if (elements->get(i) == element) return isolate->heap()->false_value(); | 9836 if (elements->get(i) == *element) return isolate->heap()->false_value(); |
| 9772 } | 9837 } |
| 9773 Object* obj; | 9838 |
| 9774 // Strict not needed. Used for cycle detection in Array join implementation. | 9839 // Strict not needed. Used for cycle detection in Array join implementation. |
| 9775 { MaybeObject* maybe_obj = | 9840 RETURN_IF_EMPTY_HANDLE(isolate, JSObject::SetFastElement(array, length, |
| 9776 array->SetFastElement(length, element, kNonStrictMode, true); | 9841 element, |
| 9777 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9842 kNonStrictMode, |
| 9778 } | 9843 true)); |
| 9779 return isolate->heap()->true_value(); | 9844 return isolate->heap()->true_value(); |
| 9780 } | 9845 } |
| 9781 | 9846 |
| 9782 | 9847 |
| 9783 /** | 9848 /** |
| 9784 * A simple visitor visits every element of Array's. | 9849 * A simple visitor visits every element of Array's. |
| 9785 * The backend storage can be a fixed array for fast elements case, | 9850 * The backend storage can be a fixed array for fast elements case, |
| 9786 * or a dictionary for sparse array. Since Dictionary is a subtype | 9851 * or a dictionary for sparse array. Since Dictionary is a subtype |
| 9787 * of FixedArray, the class can be used by both fast and slow cases. | 9852 * of FixedArray, the class can be used by both fast and slow cases. |
| 9788 * The second parameter of the constructor, fast_elements, specifies | 9853 * The second parameter of the constructor, fast_elements, specifies |
| (...skipping 4831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14620 } else { | 14685 } else { |
| 14621 access_allowed = isolate->MayNamedAccess(*object, *key, v8::ACCESS_GET) && | 14686 access_allowed = isolate->MayNamedAccess(*object, *key, v8::ACCESS_GET) && |
| 14622 isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS); | 14687 isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS); |
| 14623 } | 14688 } |
| 14624 return isolate->heap()->ToBoolean(access_allowed); | 14689 return isolate->heap()->ToBoolean(access_allowed); |
| 14625 } | 14690 } |
| 14626 | 14691 |
| 14627 | 14692 |
| 14628 static MaybeObject* ArrayConstructorCommon(Isolate* isolate, | 14693 static MaybeObject* ArrayConstructorCommon(Isolate* isolate, |
| 14629 Handle<JSFunction> constructor, | 14694 Handle<JSFunction> constructor, |
| 14630 Handle<Object> type_info, | 14695 Handle<AllocationSite> site, |
| 14631 Arguments* caller_args) { | 14696 Arguments* caller_args) { |
| 14632 bool holey = false; | 14697 bool holey = false; |
| 14633 bool can_use_type_feedback = true; | 14698 bool can_use_type_feedback = true; |
| 14634 if (caller_args->length() == 1) { | 14699 if (caller_args->length() == 1) { |
| 14635 Object* argument_one = (*caller_args)[0]; | 14700 Object* argument_one = (*caller_args)[0]; |
| 14636 if (argument_one->IsSmi()) { | 14701 if (argument_one->IsSmi()) { |
| 14637 int value = Smi::cast(argument_one)->value(); | 14702 int value = Smi::cast(argument_one)->value(); |
| 14638 if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) { | 14703 if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) { |
| 14639 // the array is a dictionary in this case. | 14704 // the array is a dictionary in this case. |
| 14640 can_use_type_feedback = false; | 14705 can_use_type_feedback = false; |
| 14641 } else if (value != 0) { | 14706 } else if (value != 0) { |
| 14642 holey = true; | 14707 holey = true; |
| 14643 } | 14708 } |
| 14644 } else { | 14709 } else { |
| 14645 // Non-smi length argument produces a dictionary | 14710 // Non-smi length argument produces a dictionary |
| 14646 can_use_type_feedback = false; | 14711 can_use_type_feedback = false; |
| 14647 } | 14712 } |
| 14648 } | 14713 } |
| 14649 | 14714 |
| 14650 JSArray* array; | 14715 JSArray* array; |
| 14651 MaybeObject* maybe_array; | 14716 MaybeObject* maybe_array; |
| 14652 if (!type_info.is_null() && | 14717 if (!site.is_null() && can_use_type_feedback) { |
| 14653 *type_info != isolate->heap()->undefined_value() && | |
| 14654 Cell::cast(*type_info)->value()->IsAllocationSite() && | |
| 14655 can_use_type_feedback) { | |
| 14656 Handle<Cell> cell = Handle<Cell>::cast(type_info); | |
| 14657 Handle<AllocationSite> site = Handle<AllocationSite>( | |
| 14658 AllocationSite::cast(cell->value()), isolate); | |
| 14659 ASSERT(!site->SitePointsToLiteral()); | |
| 14660 ElementsKind to_kind = site->GetElementsKind(); | 14718 ElementsKind to_kind = site->GetElementsKind(); |
| 14661 if (holey && !IsFastHoleyElementsKind(to_kind)) { | 14719 if (holey && !IsFastHoleyElementsKind(to_kind)) { |
| 14662 to_kind = GetHoleyElementsKind(to_kind); | 14720 to_kind = GetHoleyElementsKind(to_kind); |
| 14663 // Update the allocation site info to reflect the advice alteration. | 14721 // Update the allocation site info to reflect the advice alteration. |
| 14664 site->SetElementsKind(to_kind); | 14722 site->SetElementsKind(to_kind); |
| 14665 } | 14723 } |
| 14666 | 14724 |
| 14667 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( | 14725 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( |
| 14668 *constructor, site); | 14726 *constructor, site); |
| 14669 if (!maybe_array->To(&array)) return maybe_array; | 14727 if (!maybe_array->To(&array)) return maybe_array; |
| 14670 } else { | 14728 } else { |
| 14671 maybe_array = isolate->heap()->AllocateJSObject(*constructor); | 14729 maybe_array = isolate->heap()->AllocateJSObject(*constructor); |
| 14672 if (!maybe_array->To(&array)) return maybe_array; | 14730 if (!maybe_array->To(&array)) return maybe_array; |
| 14673 // We might need to transition to holey | 14731 // We might need to transition to holey |
| 14674 ElementsKind kind = constructor->initial_map()->elements_kind(); | 14732 ElementsKind kind = constructor->initial_map()->elements_kind(); |
| 14675 if (holey && !IsFastHoleyElementsKind(kind)) { | 14733 if (holey && !IsFastHoleyElementsKind(kind)) { |
| 14676 kind = GetHoleyElementsKind(kind); | 14734 kind = GetHoleyElementsKind(kind); |
| 14677 maybe_array = array->TransitionElementsKind(kind); | 14735 maybe_array = array->TransitionElementsKind(kind); |
| 14678 if (maybe_array->IsFailure()) return maybe_array; | 14736 if (maybe_array->IsFailure()) return maybe_array; |
| 14679 } | 14737 } |
| 14680 } | 14738 } |
| 14681 | 14739 |
| 14682 maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0, | 14740 maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0, |
| 14683 DONT_INITIALIZE_ARRAY_ELEMENTS); | 14741 DONT_INITIALIZE_ARRAY_ELEMENTS); |
| 14684 if (maybe_array->IsFailure()) return maybe_array; | 14742 if (maybe_array->IsFailure()) return maybe_array; |
| 14743 ElementsKind old_kind = array->GetElementsKind(); |
| 14685 maybe_array = ArrayConstructInitializeElements(array, caller_args); | 14744 maybe_array = ArrayConstructInitializeElements(array, caller_args); |
| 14686 if (maybe_array->IsFailure()) return maybe_array; | 14745 if (maybe_array->IsFailure()) return maybe_array; |
| 14746 if (!site.is_null() && |
| 14747 (old_kind != array->GetElementsKind() || |
| 14748 !can_use_type_feedback)) { |
| 14749 // The arguments passed in caused a transition. This kind of complexity |
| 14750 // can't be dealt with in the inlined hydrogen array constructor case. |
| 14751 // We must mark the allocationsite as un-inlinable. |
| 14752 site->SetDoNotInlineCall(); |
| 14753 } |
| 14687 return array; | 14754 return array; |
| 14688 } | 14755 } |
| 14689 | 14756 |
| 14690 | 14757 |
| 14691 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) { | 14758 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) { |
| 14692 HandleScope scope(isolate); | 14759 HandleScope scope(isolate); |
| 14693 // If we get 2 arguments then they are the stub parameters (constructor, type | 14760 // If we get 2 arguments then they are the stub parameters (constructor, type |
| 14694 // info). If we get 3, then the first one is a pointer to the arguments | 14761 // info). If we get 4, then the first one is a pointer to the arguments |
| 14695 // passed by the caller. | 14762 // passed by the caller, and the last one is the length of the arguments |
| 14763 // passed to the caller (redundant, but useful to check on the deoptimizer |
| 14764 // with an assert). |
| 14696 Arguments empty_args(0, NULL); | 14765 Arguments empty_args(0, NULL); |
| 14697 bool no_caller_args = args.length() == 2; | 14766 bool no_caller_args = args.length() == 2; |
| 14698 ASSERT(no_caller_args || args.length() == 3); | 14767 ASSERT(no_caller_args || args.length() == 4); |
| 14699 int parameters_start = no_caller_args ? 0 : 1; | 14768 int parameters_start = no_caller_args ? 0 : 1; |
| 14700 Arguments* caller_args = no_caller_args | 14769 Arguments* caller_args = no_caller_args |
| 14701 ? &empty_args | 14770 ? &empty_args |
| 14702 : reinterpret_cast<Arguments*>(args[0]); | 14771 : reinterpret_cast<Arguments*>(args[0]); |
| 14703 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); | 14772 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); |
| 14704 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1); | 14773 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1); |
| 14774 #ifdef DEBUG |
| 14775 if (!no_caller_args) { |
| 14776 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2); |
| 14777 ASSERT(arg_count == caller_args->length()); |
| 14778 } |
| 14779 #endif |
| 14780 |
| 14781 Handle<AllocationSite> site; |
| 14782 if (!type_info.is_null() && |
| 14783 *type_info != isolate->heap()->undefined_value() && |
| 14784 Cell::cast(*type_info)->value()->IsAllocationSite()) { |
| 14785 site = Handle<AllocationSite>( |
| 14786 AllocationSite::cast(Cell::cast(*type_info)->value()), isolate); |
| 14787 ASSERT(!site->SitePointsToLiteral()); |
| 14788 } |
| 14705 | 14789 |
| 14706 return ArrayConstructorCommon(isolate, | 14790 return ArrayConstructorCommon(isolate, |
| 14707 constructor, | 14791 constructor, |
| 14708 type_info, | 14792 site, |
| 14709 caller_args); | 14793 caller_args); |
| 14710 } | 14794 } |
| 14711 | 14795 |
| 14712 | 14796 |
| 14713 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) { | 14797 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) { |
| 14714 HandleScope scope(isolate); | 14798 HandleScope scope(isolate); |
| 14715 Arguments empty_args(0, NULL); | 14799 Arguments empty_args(0, NULL); |
| 14716 bool no_caller_args = args.length() == 1; | 14800 bool no_caller_args = args.length() == 1; |
| 14717 ASSERT(no_caller_args || args.length() == 2); | 14801 ASSERT(no_caller_args || args.length() == 3); |
| 14718 int parameters_start = no_caller_args ? 0 : 1; | 14802 int parameters_start = no_caller_args ? 0 : 1; |
| 14719 Arguments* caller_args = no_caller_args | 14803 Arguments* caller_args = no_caller_args |
| 14720 ? &empty_args | 14804 ? &empty_args |
| 14721 : reinterpret_cast<Arguments*>(args[0]); | 14805 : reinterpret_cast<Arguments*>(args[0]); |
| 14722 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); | 14806 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); |
| 14723 | 14807 #ifdef DEBUG |
| 14808 if (!no_caller_args) { |
| 14809 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1); |
| 14810 ASSERT(arg_count == caller_args->length()); |
| 14811 } |
| 14812 #endif |
| 14724 return ArrayConstructorCommon(isolate, | 14813 return ArrayConstructorCommon(isolate, |
| 14725 constructor, | 14814 constructor, |
| 14726 Handle<Object>::null(), | 14815 Handle<AllocationSite>::null(), |
| 14727 caller_args); | 14816 caller_args); |
| 14728 } | 14817 } |
| 14729 | 14818 |
| 14730 | 14819 |
| 14820 RUNTIME_FUNCTION(MaybeObject*, Runtime_MaxSmi) { |
| 14821 return Smi::FromInt(Smi::kMaxValue); |
| 14822 } |
| 14823 |
| 14824 |
| 14731 // ---------------------------------------------------------------------------- | 14825 // ---------------------------------------------------------------------------- |
| 14732 // Implementation of Runtime | 14826 // Implementation of Runtime |
| 14733 | 14827 |
| 14734 #define F(name, number_of_args, result_size) \ | 14828 #define F(name, number_of_args, result_size) \ |
| 14735 { Runtime::k##name, Runtime::RUNTIME, #name, \ | 14829 { Runtime::k##name, Runtime::RUNTIME, #name, \ |
| 14736 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, | 14830 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, |
| 14737 | 14831 |
| 14738 | 14832 |
| 14739 #define I(name, number_of_args, result_size) \ | 14833 #define I(name, number_of_args, result_size) \ |
| 14740 { Runtime::kInline##name, Runtime::INLINE, \ | 14834 { Runtime::kInline##name, Runtime::INLINE, \ |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14805 // Handle last resort GC and make sure to allow future allocations | 14899 // Handle last resort GC and make sure to allow future allocations |
| 14806 // to grow the heap without causing GCs (if possible). | 14900 // to grow the heap without causing GCs (if possible). |
| 14807 isolate->counters()->gc_last_resort_from_js()->Increment(); | 14901 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 14808 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 14902 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 14809 "Runtime::PerformGC"); | 14903 "Runtime::PerformGC"); |
| 14810 } | 14904 } |
| 14811 } | 14905 } |
| 14812 | 14906 |
| 14813 | 14907 |
| 14814 } } // namespace v8::internal | 14908 } } // namespace v8::internal |
| OLD | NEW |