| OLD | NEW | 
|---|
| 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #include "vm/globals.h" | 5 #include "vm/globals.h" | 
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) | 
| 7 | 7 | 
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" | 
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" | 
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" | 
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 474       Immediate(reinterpret_cast<intptr_t>(Object::null())); | 474       Immediate(reinterpret_cast<intptr_t>(Object::null())); | 
| 475   __ cmpl(EAX, raw_null); | 475   __ cmpl(EAX, raw_null); | 
| 476   __ j(NOT_EQUAL, call_target_function); | 476   __ j(NOT_EQUAL, call_target_function); | 
| 477   __ EnterStubFrame(); | 477   __ EnterStubFrame(); | 
| 478   // Load the receiver. | 478   // Load the receiver. | 
| 479   __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 479   __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 
| 480   __ movl(EAX, Address( | 480   __ movl(EAX, Address( | 
| 481       EBP, EDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize)); | 481       EBP, EDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize)); | 
| 482   __ pushl(raw_null);  // Setup space on stack for result. | 482   __ pushl(raw_null);  // Setup space on stack for result. | 
| 483   __ pushl(EAX);  // Receiver. | 483   __ pushl(EAX);  // Receiver. | 
| 484   __ pushl(ECX); | 484   __ pushl(ECX);  // ICData/MegamorphicCache. | 
| 485   __ pushl(EDX);  // Arguments descriptor array. | 485   __ pushl(EDX);  // Arguments descriptor array. | 
| 486   __ movl(EDX, EDI); | 486   __ movl(EDX, EDI); | 
| 487   // EDX: Smi-tagged arguments array length. | 487   // EDX: Smi-tagged arguments array length. | 
| 488   PushArgumentsArray(assembler); | 488   PushArgumentsArray(assembler); | 
| 489   const intptr_t kNumArgs = 4; | 489   const intptr_t kNumArgs = 4; | 
| 490   __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); | 490   __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); | 
| 491   __ Drop(4); | 491   __ Drop(4); | 
| 492   __ popl(EAX);  // Return value. | 492   __ popl(EAX);  // Return value. | 
| 493   __ LeaveFrame(); | 493   __ LeaveFrame(); | 
| 494   __ ret(); | 494   __ ret(); | 
| (...skipping 1520 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2015   const Register left = EAX; | 2015   const Register left = EAX; | 
| 2016   const Register right = EDX; | 2016   const Register right = EDX; | 
| 2017   const Register temp = ECX; | 2017   const Register temp = ECX; | 
| 2018   __ movl(left, Address(ESP, 2 * kWordSize)); | 2018   __ movl(left, Address(ESP, 2 * kWordSize)); | 
| 2019   __ movl(right, Address(ESP, 1 * kWordSize)); | 2019   __ movl(right, Address(ESP, 1 * kWordSize)); | 
| 2020   GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2020   GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 
| 2021   __ ret(); | 2021   __ ret(); | 
| 2022 } | 2022 } | 
| 2023 | 2023 | 
| 2024 | 2024 | 
| 2025 void StubCode::EmitMegamorphicLookup( | 2025 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { | 
| 2026     Assembler* assembler, Register receiver, Register cache, Register target) { | 2026   __ LoadTaggedClassIdMayBeSmi(EAX, EBX); | 
| 2027   ASSERT((cache != EAX) && (cache != EDI)); |  | 
| 2028   __ LoadTaggedClassIdMayBeSmi(EAX, receiver); |  | 
| 2029 |  | 
| 2030   // EAX: class ID of the receiver (smi). | 2027   // EAX: class ID of the receiver (smi). | 
| 2031   __ movl(EDI, FieldAddress(cache, MegamorphicCache::buckets_offset())); | 2028   __ movl(EDI, FieldAddress(ECX, MegamorphicCache::buckets_offset())); | 
| 2032   __ movl(EBX, FieldAddress(cache, MegamorphicCache::mask_offset())); | 2029   __ movl(EBX, FieldAddress(ECX, MegamorphicCache::mask_offset())); | 
| 2033   // EDI: cache buckets array. | 2030   // EDI: cache buckets array. | 
| 2034   // EBX: mask. | 2031   // EBX: mask. | 
|  | 2032   __ pushl(ECX);  // Spill MegamorphicCache. | 
| 2035   __ movl(ECX, EAX); | 2033   __ movl(ECX, EAX); | 
|  | 2034   // ECX: probe. | 
| 2036 | 2035 | 
| 2037   Label loop, update, call_target_function; | 2036   Label loop, update, load_target_function; | 
| 2038   __ jmp(&loop); | 2037   __ jmp(&loop); | 
| 2039 | 2038 | 
| 2040   __ Bind(&update); | 2039   __ Bind(&update); | 
| 2041   __ addl(ECX, Immediate(Smi::RawValue(1))); | 2040   __ addl(ECX, Immediate(Smi::RawValue(1))); | 
| 2042   __ Bind(&loop); | 2041   __ Bind(&loop); | 
| 2043   __ andl(ECX, EBX); | 2042   __ andl(ECX, EBX); | 
| 2044   const intptr_t base = Array::data_offset(); | 2043   const intptr_t base = Array::data_offset(); | 
| 2045   // ECX is smi tagged, but table entries are two words, so TIMES_4. | 2044   // ECX is smi tagged, but table entries are two words, so TIMES_4. | 
| 2046   __ movl(EDX, FieldAddress(EDI, ECX, TIMES_4, base)); | 2045   __ movl(EDX, FieldAddress(EDI, ECX, TIMES_4, base)); | 
| 2047 | 2046 | 
| 2048   ASSERT(kIllegalCid == 0); | 2047   ASSERT(kIllegalCid == 0); | 
| 2049   __ testl(EDX, EDX); | 2048   __ testl(EDX, EDX); | 
| 2050   __ j(ZERO, &call_target_function, Assembler::kNearJump); | 2049   __ j(ZERO, &load_target_function, Assembler::kNearJump); | 
| 2051   __ cmpl(EDX, EAX); | 2050   __ cmpl(EDX, EAX); | 
| 2052   __ j(NOT_EQUAL, &update, Assembler::kNearJump); | 2051   __ j(NOT_EQUAL, &update, Assembler::kNearJump); | 
| 2053 | 2052 | 
| 2054   __ Bind(&call_target_function); | 2053   __ Bind(&load_target_function); | 
| 2055   // Call the target found in the cache.  For a class id match, this is a | 2054   // Call the target found in the cache.  For a class id match, this is a | 
| 2056   // proper target for the given name and arguments descriptor.  If the | 2055   // proper target for the given name and arguments descriptor.  If the | 
| 2057   // illegal class id was found, the target is a cache miss handler that can | 2056   // illegal class id was found, the target is a cache miss handler that can | 
| 2058   // be invoked as a normal Dart function. | 2057   // be invoked as a normal Dart function. | 
| 2059   __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize)); | 2058   __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize)); | 
| 2060   __ movl(target, FieldAddress(EAX, Function::entry_point_offset())); | 2059   __ popl(ECX);  // Restore MegamorphicCache. | 
|  | 2060   __ movl(EDX, | 
|  | 2061           FieldAddress(ECX, MegamorphicCache::arguments_descriptor_offset())); | 
|  | 2062   __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset())); | 
| 2061 } | 2063 } | 
| 2062 | 2064 | 
| 2063 | 2065 | 
| 2064 // Called from megamorphic calls. | 2066 // Called from megamorphic calls. | 
| 2065 //  ECX: receiver. | 2067 //  EBX: receiver | 
| 2066 //  EBX: lookup cache. | 2068 //  ECX: MegamorphicCache (preserved) | 
| 2067 // Result: | 2069 // Result: | 
| 2068 //  EBX: entry point. | 2070 //  EBX: target entry point | 
|  | 2071 //  EDX: argument descriptor | 
| 2069 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2072 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 
| 2070   EmitMegamorphicLookup(assembler, ECX, EBX, EBX); | 2073   EmitMegamorphicLookup(assembler); | 
| 2071   __ ret(); | 2074   __ ret(); | 
| 2072 } | 2075 } | 
| 2073 | 2076 | 
| 2074 | 2077 | 
|  | 2078 // Called from switchable IC calls. | 
|  | 2079 //  EBX: receiver | 
|  | 2080 //  ECX: ICData (preserved) | 
|  | 2081 // Result: | 
|  | 2082 //  EBX: target entry point | 
|  | 2083 //  EDX: arguments descriptor | 
|  | 2084 void StubCode::GenerateICLookupStub(Assembler* assembler) { | 
|  | 2085   __ int3(); | 
|  | 2086 } | 
|  | 2087 | 
| 2075 }  // namespace dart | 2088 }  // namespace dart | 
| 2076 | 2089 | 
| 2077 #endif  // defined TARGET_ARCH_IA32 | 2090 #endif  // defined TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|