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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 #include "misc-intrinsics.h" | 54 #include "misc-intrinsics.h" |
55 #include "parser.h" | 55 #include "parser.h" |
56 #include "platform.h" | 56 #include "platform.h" |
57 #include "runtime-profiler.h" | 57 #include "runtime-profiler.h" |
58 #include "runtime.h" | 58 #include "runtime.h" |
59 #include "scopeinfo.h" | 59 #include "scopeinfo.h" |
60 #include "smart-pointers.h" | 60 #include "smart-pointers.h" |
61 #include "string-search.h" | 61 #include "string-search.h" |
62 #include "stub-cache.h" | 62 #include "stub-cache.h" |
63 #include "uri.h" | 63 #include "uri.h" |
64 #include "v8conversions.h" | |
64 #include "v8threads.h" | 65 #include "v8threads.h" |
65 #include "vm-state-inl.h" | 66 #include "vm-state-inl.h" |
66 | 67 |
67 namespace v8 { | 68 namespace v8 { |
68 namespace internal { | 69 namespace internal { |
69 | 70 |
70 | 71 |
71 #define RUNTIME_ASSERT(value) \ | 72 #define RUNTIME_ASSERT(value) \ |
72 if (!(value)) return isolate->ThrowIllegalOperation(); | 73 if (!(value)) return isolate->ThrowIllegalOperation(); |
73 | 74 |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
631 | 632 |
632 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { | 633 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { |
633 NoHandleAllocation ha(isolate); | 634 NoHandleAllocation ha(isolate); |
634 ASSERT(args.length() == 1); | 635 ASSERT(args.length() == 1); |
635 CONVERT_ARG_CHECKED(JSProxy, proxy, 0); | 636 CONVERT_ARG_CHECKED(JSProxy, proxy, 0); |
636 proxy->Fix(); | 637 proxy->Fix(); |
637 return isolate->heap()->undefined_value(); | 638 return isolate->heap()->undefined_value(); |
638 } | 639 } |
639 | 640 |
640 | 641 |
641 static size_t ArrayBufferAllocatedLength(Isolate* isolate, | |
642 JSArrayBuffer* buffer) { | |
643 NoHandleAllocation hc(isolate); | |
644 Object* byte_length = buffer->byte_length(); | |
645 if (byte_length->IsSmi()) { | |
646 return Smi::cast(byte_length)->value(); | |
647 } else { | |
648 double value = HeapNumber::cast(byte_length)->value(); | |
649 return static_cast<size_t>(value); | |
650 } | |
651 } | |
652 | |
653 | |
654 static void ArrayBufferWeakCallback(v8::Isolate* external_isolate, | 642 static void ArrayBufferWeakCallback(v8::Isolate* external_isolate, |
655 Persistent<Value> object, | 643 Persistent<Value> object, |
656 void* data) { | 644 void* data) { |
657 Isolate* isolate = reinterpret_cast<Isolate*>(external_isolate); | 645 Isolate* isolate = reinterpret_cast<Isolate*>(external_isolate); |
658 HandleScope scope(isolate); | 646 HandleScope scope(isolate); |
659 Handle<Object> internal_object = Utils::OpenHandle(*object); | 647 Handle<Object> internal_object = Utils::OpenHandle(*object); |
660 | 648 |
661 size_t allocated_length = ArrayBufferAllocatedLength( | 649 size_t allocated_length = NumberToSize( |
662 isolate, JSArrayBuffer::cast(*internal_object)); | 650 isolate, JSArrayBuffer::cast(*internal_object)->byte_length()); |
663 isolate->heap()->AdjustAmountOfExternalAllocatedMemory( | 651 isolate->heap()->AdjustAmountOfExternalAllocatedMemory( |
664 -static_cast<intptr_t>(allocated_length)); | 652 -static_cast<intptr_t>(allocated_length)); |
665 if (data != NULL) | 653 if (data != NULL) |
666 free(data); | 654 free(data); |
667 object.Dispose(external_isolate); | 655 object.Dispose(external_isolate); |
668 } | 656 } |
669 | 657 |
670 | 658 |
671 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { | 659 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { |
672 HandleScope scope(isolate); | 660 HandleScope scope(isolate); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
737 } | 725 } |
738 | 726 |
739 | 727 |
740 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) { | 728 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) { |
741 HandleScope scope(isolate); | 729 HandleScope scope(isolate); |
742 ASSERT(args.length() == 3); | 730 ASSERT(args.length() == 3); |
743 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0); | 731 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0); |
744 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1); | 732 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1); |
745 CONVERT_DOUBLE_ARG_CHECKED(first, 2); | 733 CONVERT_DOUBLE_ARG_CHECKED(first, 2); |
746 size_t start = static_cast<size_t>(first); | 734 size_t start = static_cast<size_t>(first); |
747 size_t target_length = ArrayBufferAllocatedLength(isolate, *target); | 735 size_t target_length = NumberToSize(isolate, target->byte_length()); |
748 | 736 |
749 if (target_length == 0) | 737 if (target_length == 0) |
750 return isolate->heap()->undefined_value(); | 738 return isolate->heap()->undefined_value(); |
751 | 739 |
752 ASSERT(ArrayBufferAllocatedLength(isolate, *source) - target_length >= start); | 740 ASSERT(NumberToSize(isolate, source->byte_length()) - target_length >= start); |
753 uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store()); | 741 uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store()); |
754 uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store()); | 742 uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store()); |
755 CopyBytes(target_data, source_data + start, target_length); | 743 CopyBytes(target_data, source_data + start, target_length); |
756 return isolate->heap()->undefined_value(); | 744 return isolate->heap()->undefined_value(); |
757 } | 745 } |
758 | 746 |
759 | 747 |
748 enum TypedArrayId { | |
749 // arrayIds below should be synchromized with typedarray.js natives. | |
750 ARRAY_ID_UINT8 = 1, | |
751 ARRAY_ID_INT8 = 2, | |
752 ARRAY_ID_UINT16 = 3, | |
753 ARRAY_ID_INT16 = 4, | |
754 ARRAY_ID_UINT32 = 5, | |
755 ARRAY_ID_INT32 = 6, | |
756 ARRAY_ID_FLOAT32 = 7, | |
757 ARRAY_ID_FLOAT64 = 8 | |
758 }; | |
759 | |
760 | |
761 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) { | |
762 HandleScope scope(isolate); | |
763 ASSERT(args.length() == 5); | |
764 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); | |
765 CONVERT_SMI_ARG_CHECKED(arrayId, 1); | |
766 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 2); | |
767 CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3); | |
768 CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4); | |
769 | |
770 ExternalArrayType arrayType; | |
771 ElementsKind elementsKind; | |
772 size_t elementSize; | |
773 switch (arrayId) { | |
774 case ARRAY_ID_UINT8: | |
775 elementsKind = EXTERNAL_UNSIGNED_BYTE_ELEMENTS; | |
776 arrayType = kExternalUnsignedByteArray; | |
777 elementSize = 1; | |
778 break; | |
779 case ARRAY_ID_INT8: | |
780 elementsKind = EXTERNAL_BYTE_ELEMENTS; | |
781 arrayType = kExternalByteArray; | |
782 elementSize = 1; | |
783 break; | |
784 case ARRAY_ID_UINT16: | |
785 elementsKind = EXTERNAL_UNSIGNED_SHORT_ELEMENTS; | |
786 arrayType = kExternalUnsignedShortArray; | |
787 elementSize = 2; | |
788 break; | |
789 case ARRAY_ID_INT16: | |
790 elementsKind = EXTERNAL_SHORT_ELEMENTS; | |
791 arrayType = kExternalShortArray; | |
792 elementSize = 2; | |
793 break; | |
794 case ARRAY_ID_UINT32: | |
795 elementsKind = EXTERNAL_UNSIGNED_INT_ELEMENTS; | |
796 arrayType = kExternalUnsignedIntArray; | |
797 elementSize = 4; | |
798 break; | |
799 case ARRAY_ID_INT32: | |
800 elementsKind = EXTERNAL_INT_ELEMENTS; | |
801 arrayType = kExternalIntArray; | |
802 elementSize = 4; | |
803 break; | |
804 case ARRAY_ID_FLOAT32: | |
805 elementsKind = EXTERNAL_FLOAT_ELEMENTS; | |
806 arrayType = kExternalFloatArray; | |
807 elementSize = 4; | |
808 break; | |
809 case ARRAY_ID_FLOAT64: | |
810 elementsKind = EXTERNAL_DOUBLE_ELEMENTS; | |
811 arrayType = kExternalDoubleArray; | |
812 elementSize = 8; | |
813 break; | |
814 default: | |
815 UNREACHABLE(); | |
816 } | |
817 | |
818 holder->set_buffer(*buffer); | |
819 holder->set_byte_offset(*byte_offset_object); | |
820 holder->set_byte_length(*byte_length_object); | |
821 | |
822 size_t byte_offset = NumberToSize(isolate, *byte_offset_object); | |
823 size_t byte_length = NumberToSize(isolate, *byte_length_object); | |
824 ASSERT(byte_length % elementSize == 0); | |
rossberg
2013/04/16 13:30:43
I'm surprised that you dropped length instead of b
Dmitry Lomov (no reviews)
2013/04/16 13:47:13
More rigid invariant is better, no? This helps cat
rossberg
2013/04/16 13:59:48
No, the simpler the invariant/precondition of a fu
| |
825 size_t length = byte_length / elementSize; | |
826 | |
827 Object* length_object; | |
828 { | |
rossberg
2013/04/16 13:30:43
You can use factory->NewNumber for this.
Dmitry Lomov (no reviews)
2013/04/16 13:47:13
Done.
| |
829 MaybeObject* maybe_length = | |
830 isolate->heap()->NumberFromDouble(static_cast<double>(length)); | |
831 if (!maybe_length->ToObject(&length_object)) return maybe_length; | |
832 } | |
833 CHECK(length_object->IsSmi() || length_object->IsHeapNumber()); | |
834 holder->set_length(length_object); | |
835 | |
836 Handle<ExternalArray> elements = | |
837 isolate->factory()->NewExternalArray( | |
838 length, arrayType, | |
839 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); | |
840 Handle<Map> map = | |
841 isolate->factory()->GetElementsTransitionMap(holder, elementsKind); | |
842 holder->set_map(*map); | |
843 holder->set_elements(*elements); | |
844 return isolate->heap()->undefined_value(); | |
845 } | |
846 | |
847 | |
848 #define TYPED_ARRAY_GETTER(getter, accessor) \ | |
849 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) { \ | |
850 HandleScope scope(isolate); \ | |
851 ASSERT(args.length() == 1); \ | |
852 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); \ | |
853 return holder->accessor(); \ | |
854 } | |
855 | |
856 TYPED_ARRAY_GETTER(Buffer, buffer) | |
857 TYPED_ARRAY_GETTER(ByteLength, byte_length) | |
858 TYPED_ARRAY_GETTER(ByteOffset, byte_offset) | |
859 TYPED_ARRAY_GETTER(Length, length) | |
860 | |
861 #undef TYPED_ARRAY_GETTER | |
862 | |
760 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { | 863 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { |
761 HandleScope scope(isolate); | 864 HandleScope scope(isolate); |
762 ASSERT(args.length() == 1); | 865 ASSERT(args.length() == 1); |
763 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); | 866 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); |
764 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); | 867 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); |
765 holder->set_table(*table); | 868 holder->set_table(*table); |
766 return *holder; | 869 return *holder; |
767 } | 870 } |
768 | 871 |
769 | 872 |
(...skipping 12314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13084 // Handle last resort GC and make sure to allow future allocations | 13187 // Handle last resort GC and make sure to allow future allocations |
13085 // to grow the heap without causing GCs (if possible). | 13188 // to grow the heap without causing GCs (if possible). |
13086 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13189 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13087 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13190 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13088 "Runtime::PerformGC"); | 13191 "Runtime::PerformGC"); |
13089 } | 13192 } |
13090 } | 13193 } |
13091 | 13194 |
13092 | 13195 |
13093 } } // namespace v8::internal | 13196 } } // namespace v8::internal |
OLD | NEW |