Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // | 4 // |
| 5 // The intrinsic code below is executed before a method has built its frame. | 5 // The intrinsic code below is executed before a method has built its frame. |
| 6 // The return address is on the stack and the arguments below it. | 6 // The return address is on the stack and the arguments below it. |
| 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. | 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. |
| 8 // Each intrinsification method returns true if the corresponding | 8 // Each intrinsification method returns true if the corresponding |
| 9 // Dart method was intrinsified. | 9 // Dart method was intrinsified. |
| 10 | 10 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 V(ObjectArray, [], Array_getIndexed) \ | 68 V(ObjectArray, [], Array_getIndexed) \ |
| 69 V(ObjectArray, []=, Array_setIndexed) \ | 69 V(ObjectArray, []=, Array_setIndexed) \ |
| 70 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ | 70 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ |
| 71 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ | 71 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ |
| 72 V(ImmutableArray, [], Array_getIndexed) \ | 72 V(ImmutableArray, [], Array_getIndexed) \ |
| 73 V(ImmutableArray, get:length, Array_getLength) \ | 73 V(ImmutableArray, get:length, Array_getLength) \ |
| 74 V(Math, sqrt, Math_sqrt) \ | 74 V(Math, sqrt, Math_sqrt) \ |
| 75 V(Object, ==, Object_equal) \ | 75 V(Object, ==, Object_equal) \ |
| 76 V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \ | 76 V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \ |
| 77 V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \ | 77 V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \ |
| 78 V(StringBase, get:length, String_getLength) \ | |
| 79 V(StringBase, charCodeAt, String_charCodeAt) \ | |
| 80 V(StringBase, hashCode, String_hashCode) \ | |
| 78 | 81 |
| 79 #define __ assembler-> | 82 #define __ assembler-> |
| 80 | 83 |
| 81 static bool ObjectArray_Allocate(Assembler* assembler) { | 84 static bool ObjectArray_Allocate(Assembler* assembler) { |
| 82 // This snippet of inlined code uses the following registers: | 85 // This snippet of inlined code uses the following registers: |
| 83 // EAX, EBX, EDI | 86 // EAX, EBX, EDI |
| 84 // and the newly allocated object is returned in EAX. | 87 // and the newly allocated object is returned in EAX. |
| 85 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; | 88 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; |
| 86 const intptr_t kArrayLengthOffset = 1 * kWordSize; | 89 const intptr_t kArrayLengthOffset = 1 * kWordSize; |
| 87 Label fall_through; | 90 Label fall_through; |
| (...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 __ LoadObject(EAX, bool_false); | 893 __ LoadObject(EAX, bool_false); |
| 891 __ ret(); | 894 __ ret(); |
| 892 __ Bind(&is_true); | 895 __ Bind(&is_true); |
| 893 __ LoadObject(EAX, bool_true); | 896 __ LoadObject(EAX, bool_true); |
| 894 __ ret(); | 897 __ ret(); |
| 895 __ Bind(&fall_through); | 898 __ Bind(&fall_through); |
| 896 return false; | 899 return false; |
| 897 } | 900 } |
| 898 | 901 |
| 899 | 902 |
| 903 static bool String_getLength(Assembler* assembler) { | |
| 904 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | |
|
siva
2011/11/02 20:22:06
// String object.
srdjan
2011/11/02 20:31:42
Done.
| |
| 905 __ movl(EAX, FieldAddress(EAX, String::length_offset())); | |
| 906 __ ret(); | |
| 907 return true; | |
| 908 } | |
| 909 | |
| 910 | |
| 911 // TODO(srdjan): Implement for two and four byte strings as well. | |
| 912 static bool String_charCodeAt(Assembler* assembler) { | |
| 913 ObjectStore* object_store = Isolate::Current()->object_store(); | |
| 914 Label fall_through; | |
| 915 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. | |
| 916 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. | |
|
siva
2011/11/02 20:22:06
// String object. (not Array)
srdjan
2011/11/02 20:31:42
Done.
| |
| 917 __ testl(EBX, Immediate(kSmiTagMask)); | |
| 918 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | |
| 919 // Range check. | |
| 920 __ cmpl(EBX, FieldAddress(EAX, String::length_offset())); | |
| 921 // Runtime throws exception. | |
| 922 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | |
| 923 __ movl(EDI, FieldAddress(EAX, Instance::class_offset())); | |
| 924 __ CompareObject(EDI, | |
| 925 Class::ZoneHandle(object_store->one_byte_string_class())); | |
| 926 __ j(NOT_EQUAL, &fall_through); | |
| 927 __ SmiUntag(EBX); | |
| 928 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset())); | |
| 929 __ SmiTag(EAX); | |
| 930 __ ret(); | |
| 931 __ Bind(&fall_through); | |
| 932 return false; | |
| 933 } | |
| 934 | |
| 935 | |
| 936 static bool String_hashCode(Assembler* assembler) { | |
| 937 Label fall_through; | |
| 938 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | |
|
siva
2011/11/02 20:22:06
// String object.
srdjan
2011/11/02 20:31:42
Done.
| |
| 939 __ movl(EAX, FieldAddress(EAX, String::hash_offset())); | |
| 940 __ cmpl(EAX, Immediate(0)); | |
| 941 __ j(EQUAL, &fall_through, Assembler::kNearJump); | |
|
siva
2011/11/02 20:22:06
// Hash not computed yet.
srdjan
2011/11/02 20:31:42
Done.
| |
| 942 __ ret(); | |
| 943 __ Bind(&fall_through); | |
| 944 return false; | |
| 945 } | |
| 946 | |
| 900 #undef __ | 947 #undef __ |
| 901 | 948 |
| 902 | 949 |
| 903 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { | 950 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { |
| 904 if (!FLAG_intrinsify) return false; | 951 if (!FLAG_intrinsify) return false; |
| 905 const char* function_name = String::Handle(function.name()).ToCString(); | 952 const char* function_name = String::Handle(function.name()).ToCString(); |
| 906 const Class& function_class = Class::Handle(function.owner()); | 953 const Class& function_class = Class::Handle(function.owner()); |
| 907 const char* class_name = String::Handle(function_class.Name()).ToCString(); | 954 const char* class_name = String::Handle(function_class.Name()).ToCString(); |
| 908 #define FIND_INTRINSICS(test_class_name, test_function_name, destination) \ | 955 #define FIND_INTRINSICS(test_class_name, test_function_name, destination) \ |
| 909 if ((strcmp(#test_function_name, function_name) == 0) && \ | 956 if ((strcmp(#test_function_name, function_name) == 0) && \ |
| 910 (strcmp(#test_class_name, class_name) == 0)) { \ | 957 (strcmp(#test_class_name, class_name) == 0)) { \ |
| 911 return destination(assembler); \ | 958 return destination(assembler); \ |
| 912 } \ | 959 } \ |
| 913 | 960 |
| 914 INTRINSIC_LIST(FIND_INTRINSICS); | 961 INTRINSIC_LIST(FIND_INTRINSICS); |
| 915 #undef FIND_INTRINSICS | 962 #undef FIND_INTRINSICS |
| 916 return false; | 963 return false; |
| 917 } | 964 } |
| 918 | 965 |
| 919 } // namespace dart | 966 } // namespace dart |
| 920 | 967 |
| 921 #endif // defined TARGET_ARCH_IA32 | 968 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |