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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 V(Double, Double.fromInteger, Double_fromInteger) \ | 66 V(Double, Double.fromInteger, Double_fromInteger) \ |
| 67 V(Double, isNaN, Double_isNaN) \ | 67 V(Double, isNaN, Double_isNaN) \ |
| 68 V(Double, isNegative, Double_isNegative) \ | 68 V(Double, isNegative, Double_isNegative) \ |
| 69 V(ObjectArray, ObjectArray., ObjectArray_Allocate) \ | 69 V(ObjectArray, ObjectArray., ObjectArray_Allocate) \ |
| 70 V(ObjectArray, get:length, Array_getLength) \ | 70 V(ObjectArray, get:length, Array_getLength) \ |
| 71 V(ObjectArray, [], Array_getIndexed) \ | 71 V(ObjectArray, [], Array_getIndexed) \ |
| 72 V(ObjectArray, []=, Array_setIndexed) \ | 72 V(ObjectArray, []=, Array_setIndexed) \ |
| 73 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ | 73 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ |
| 74 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ | 74 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ |
| 75 V(GrowableObjectArray, []=, GrowableArray_setIndexed) \ | 75 V(GrowableObjectArray, []=, GrowableArray_setIndexed) \ |
| 76 V(_ByteArrayBase, get:length, ByteArrayBase_getLength) \ | |
| 77 V(_ByteArrayBase, [], ByteArrayBase_getIndexed) \ | |
|
siva
2012/02/11 01:39:29
The more interesting ones are the getInt8, getUint
srdjan
2012/02/12 06:52:24
Do we have existing code/benchmarks that are alrea
| |
| 76 V(ImmutableArray, [], Array_getIndexed) \ | 78 V(ImmutableArray, [], Array_getIndexed) \ |
| 77 V(ImmutableArray, get:length, Array_getLength) \ | 79 V(ImmutableArray, get:length, Array_getLength) \ |
| 78 V(Math, sqrt, Math_sqrt) \ | 80 V(Math, sqrt, Math_sqrt) \ |
| 79 V(Math, sin, Math_sin) \ | 81 V(Math, sin, Math_sin) \ |
| 80 V(Math, cos, Math_cos) \ | 82 V(Math, cos, Math_cos) \ |
| 81 V(Object, ==, Object_equal) \ | 83 V(Object, ==, Object_equal) \ |
| 82 V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \ | 84 V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \ |
| 83 V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \ | 85 V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \ |
| 84 V(StringBase, get:length, String_getLength) \ | 86 V(StringBase, get:length, String_getLength) \ |
| 85 V(StringBase, charCodeAt, String_charCodeAt) \ | 87 V(StringBase, charCodeAt, String_charCodeAt) \ |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 ASSERT(kSmiTagShift == 1); | 323 ASSERT(kSmiTagShift == 1); |
| 322 __ StoreIntoObject(EAX, | 324 __ StoreIntoObject(EAX, |
| 323 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), | 325 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), |
| 324 EDI); | 326 EDI); |
| 325 __ ret(); | 327 __ ret(); |
| 326 __ Bind(&fall_through); | 328 __ Bind(&fall_through); |
| 327 return false; | 329 return false; |
| 328 } | 330 } |
| 329 | 331 |
| 330 | 332 |
| 333 // Handles only class InternalByteArray. | |
|
siva
2012/02/11 01:39:29
Would you at some point also implement a similar i
srdjan
2012/02/12 06:52:24
Yes.
| |
| 334 static bool ByteArrayBase_getLength(Assembler* assembler) { | |
| 335 ObjectStore* object_store = Isolate::Current()->object_store(); | |
| 336 Label fall_through; | |
| 337 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | |
| 338 __ movl(EBX, FieldAddress(EAX, Object::class_offset())); | |
| 339 __ CompareObject(EBX, | |
| 340 Class::ZoneHandle(object_store->internal_byte_array_class())); | |
| 341 __ j(NOT_EQUAL, &fall_through); | |
| 342 __ movl(EAX, FieldAddress(EAX, InternalByteArray::length_offset())); | |
| 343 __ ret(); | |
| 344 __ Bind(&fall_through); | |
| 345 return false; | |
| 346 } | |
| 347 | |
| 348 | |
| 349 // Handles only class InternalByteArray. | |
| 350 static bool ByteArrayBase_getIndexed(Assembler* assembler) { | |
| 351 ObjectStore* object_store = Isolate::Current()->object_store(); | |
| 352 Label fall_through; | |
| 353 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. | |
| 354 __ movl(EBX, FieldAddress(EAX, Object::class_offset())); | |
| 355 __ CompareObject(EBX, | |
| 356 Class::ZoneHandle(object_store->internal_byte_array_class())); | |
| 357 __ j(NOT_EQUAL, &fall_through); | |
| 358 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. | |
| 359 __ testl(EBX, Immediate(kSmiTagMask)); | |
| 360 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | |
| 361 // Range check. | |
| 362 __ cmpl(EBX, FieldAddress(EAX, InternalByteArray::length_offset())); | |
| 363 // Runtime throws exception. | |
| 364 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | |
| 365 __ SmiUntag(EBX); | |
| 366 __ movzxb(EAX, | |
| 367 FieldAddress(EAX, EBX, TIMES_1, InternalByteArray::data_offset())); | |
| 368 __ SmiTag(EAX); | |
|
siva
2012/02/11 01:39:29
Perhaps a comment that values stored in the byte a
srdjan
2012/02/12 06:52:24
Done.
| |
| 369 __ ret(); | |
| 370 __ Bind(&fall_through); | |
| 371 return false; | |
| 372 } | |
| 373 | |
| 374 | |
| 331 // Tests if two top most arguments are smis, jumps to label not_smi if not. | 375 // Tests if two top most arguments are smis, jumps to label not_smi if not. |
| 332 // Topmost argument is in EAX. | 376 // Topmost argument is in EAX. |
| 333 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { | 377 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { |
| 334 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 378 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 335 __ movl(EBX, Address(ESP, + 2 * kWordSize)); | 379 __ movl(EBX, Address(ESP, + 2 * kWordSize)); |
| 336 __ orl(EBX, EAX); | 380 __ orl(EBX, EAX); |
| 337 __ testl(EBX, Immediate(kSmiTagMask)); | 381 __ testl(EBX, Immediate(kSmiTagMask)); |
| 338 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); | 382 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); |
| 339 } | 383 } |
| 340 | 384 |
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1147 } | 1191 } |
| 1148 | 1192 |
| 1149 #undef __ | 1193 #undef __ |
| 1150 | 1194 |
| 1151 | 1195 |
| 1152 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { | 1196 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { |
| 1153 if (!FLAG_intrinsify) return false; | 1197 if (!FLAG_intrinsify) return false; |
| 1154 const char* function_name = String::Handle(function.name()).ToCString(); | 1198 const char* function_name = String::Handle(function.name()).ToCString(); |
| 1155 const Class& function_class = Class::Handle(function.owner()); | 1199 const Class& function_class = Class::Handle(function.owner()); |
| 1156 const char* class_name = String::Handle(function_class.Name()).ToCString(); | 1200 const char* class_name = String::Handle(function_class.Name()).ToCString(); |
| 1201 // Only core library methods can be intrinsified. | |
| 1202 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | |
| 1203 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); | |
| 1204 if ((function_class.library() != core_lib.raw()) && | |
| 1205 (function_class.library() != core_impl_lib.raw())) { | |
| 1206 return false; | |
| 1207 } | |
| 1157 #define FIND_INTRINSICS(test_class_name, test_function_name, destination) \ | 1208 #define FIND_INTRINSICS(test_class_name, test_function_name, destination) \ |
| 1158 if ((strcmp(#test_function_name, function_name) == 0) && \ | 1209 if ((#test_class_name[0] == '_') && (class_name[0] == '_')) { \ |
| 1159 (strcmp(#test_class_name, class_name) == 0)) { \ | 1210 if (strcmp(#test_function_name, function_name) == 0) { \ |
| 1160 return destination(assembler); \ | 1211 String& test_str = String::Handle(String::New(#test_class_name)); \ |
| 1212 String& test_str_with_key = String::Handle(); \ | |
| 1213 test_str_with_key = \ | |
| 1214 String::Concat(test_str, String::Handle(core_lib.private_key())); \ | |
| 1215 if (strcmp(test_str_with_key.ToCString(), class_name) == 0) { \ | |
| 1216 return destination(assembler); \ | |
| 1217 } \ | |
| 1218 test_str_with_key = \ | |
| 1219 String::Concat(test_str, \ | |
| 1220 String::Handle(core_impl_lib.private_key())); \ | |
| 1221 if (strcmp(test_str_with_key.ToCString(), class_name) == 0) { \ | |
| 1222 return destination(assembler); \ | |
| 1223 } \ | |
| 1224 } \ | |
|
siva
2012/02/11 01:39:29
This piece of code here seems too big to repeat fo
srdjan
2012/02/12 06:52:24
Good point. Done.
| |
| 1225 } else { \ | |
| 1226 if ((strcmp(#test_function_name, function_name) == 0) && \ | |
| 1227 (strcmp(#test_class_name, class_name) == 0)) { \ | |
| 1228 return destination(assembler); \ | |
| 1229 } \ | |
| 1161 } \ | 1230 } \ |
| 1162 | 1231 |
| 1163 INTRINSIC_LIST(FIND_INTRINSICS); | 1232 INTRINSIC_LIST(FIND_INTRINSICS); |
| 1164 #undef FIND_INTRINSICS | 1233 #undef FIND_INTRINSICS |
| 1165 return false; | 1234 return false; |
| 1166 } | 1235 } |
| 1167 | 1236 |
| 1168 } // namespace dart | 1237 } // namespace dart |
| 1169 | 1238 |
| 1170 #endif // defined TARGET_ARCH_IA32 | 1239 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |