| 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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/ic_stubs.h" | 8 #include "vm/ic_stubs.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 TestEaxIsSmi test_smi(instruction_address); | 186 TestEaxIsSmi test_smi(instruction_address); |
| 187 // The target of the Smi test determines if the test should cause | 187 // The target of the Smi test determines if the test should cause |
| 188 // IC miss if successful or jump to target (IC hit). Target of IC miss is the | 188 // IC miss if successful or jump to target (IC hit). Target of IC miss is the |
| 189 // stub code, target of IC success is a code object. | 189 // stub code, target of IC success is a code object. |
| 190 CodeIndexTable* ci_table = Isolate::Current()->code_index_table(); | 190 CodeIndexTable* ci_table = Isolate::Current()->code_index_table(); |
| 191 ASSERT(ci_table != NULL); | 191 ASSERT(ci_table != NULL); |
| 192 | 192 |
| 193 Instructions& inst = Instructions::Handle( | 193 Instructions& inst = Instructions::Handle( |
| 194 Instructions::FromEntryPoint(ic_entry_point)); | 194 Instructions::FromEntryPoint(ic_entry_point)); |
| 195 ASSERT(!inst.IsNull()); | 195 ASSERT(!inst.IsNull()); |
| 196 ICData ic_data(Code::Handle(inst.code())); | |
| 197 if (patch_code) { | |
| 198 const Function& from_function = | |
| 199 Function::Handle(ci_table->LookupFunction(from)); | |
| 200 const Function& to_function = | |
| 201 Function::Handle(ci_table->LookupFunction(to)); | |
| 202 ic_data.ChangeTargets(from_function, to_function); | |
| 203 } | |
| 204 | 196 |
| 205 if (!StubCode::InCallInstanceFunctionStubCode(test_smi.TargetAddress())) { | 197 if (!StubCode::InCallInstanceFunctionStubCode(test_smi.TargetAddress())) { |
| 206 // Jump is an IC success. | 198 // Jump is an IC success. |
| 207 if (patch_code && (test_smi.TargetAddress() == from)) { | 199 if (patch_code && (test_smi.TargetAddress() == from)) { |
| 208 test_smi.SetTargetAddress(to); | 200 test_smi.SetTargetAddress(to); |
| 209 } | 201 } |
| 210 const Class& smi_class = | 202 const Class& smi_class = |
| 211 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class()); | 203 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class()); |
| 212 const Code& smi_code = | 204 const Code& smi_code = |
| 213 Code::Handle(ci_table->LookupCode(test_smi.TargetAddress())); | 205 Code::Handle(ci_table->LookupCode(test_smi.TargetAddress())); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 227 // Part B: Load receiver's class, compare with all known classes. | 219 // Part B: Load receiver's class, compare with all known classes. |
| 228 LoadObjectClass load_object_class(instruction_address); | 220 LoadObjectClass load_object_class(instruction_address); |
| 229 if (!load_object_class.IsValid()) { | 221 if (!load_object_class.IsValid()) { |
| 230 return false; | 222 return false; |
| 231 } | 223 } |
| 232 instruction_address += load_object_class.pattern_length_in_bytes(); | 224 instruction_address += load_object_class.pattern_length_in_bytes(); |
| 233 while (true) { | 225 while (true) { |
| 234 ICCheckReceiverClass check_class(instruction_address); | 226 ICCheckReceiverClass check_class(instruction_address); |
| 235 if (!check_class.IsValid()) { | 227 if (!check_class.IsValid()) { |
| 236 // Done parsing. | 228 // Done parsing. |
| 237 #if defined(DEBUG) | |
| 238 // Classes can be set to NULL if we do not care about collecting them. | |
| 239 if (classes != NULL) { | |
| 240 ic_data.CheckIsSame(classes, targets); | |
| 241 } | |
| 242 #endif | |
| 243 return true; | 229 return true; |
| 244 } | 230 } |
| 245 if (patch_code && (check_class.TargetAddress() == from)) { | 231 if (patch_code && (check_class.TargetAddress() == from)) { |
| 246 check_class.SetTargetAddress(to); | 232 check_class.SetTargetAddress(to); |
| 247 } | 233 } |
| 248 const Class& cls = Class::ZoneHandle(check_class.TestClass()); | 234 const Class& cls = Class::ZoneHandle(check_class.TestClass()); |
| 249 const Code& code = Code::ZoneHandle( | 235 const Code& code = Code::ZoneHandle( |
| 250 ci_table->LookupCode(check_class.TargetAddress())); | 236 ci_table->LookupCode(check_class.TargetAddress())); |
| 251 ASSERT(!cls.IsNullClass()); | 237 ASSERT(!cls.IsNullClass()); |
| 252 ASSERT(!code.IsNull()); | 238 ASSERT(!code.IsNull()); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 Function::Handle( | 341 Function::Handle( |
| 356 code_index_table->LookupFunction(target.EntryPoint())); | 342 code_index_table->LookupFunction(target.EntryPoint())); |
| 357 OS::Print("%d: Code for inline cache for class '%s' function '%s': {\n", | 343 OS::Print("%d: Code for inline cache for class '%s' function '%s': {\n", |
| 358 i, class_name.ToCString(), function.ToFullyQualifiedCString()); | 344 i, class_name.ToCString(), function.ToFullyQualifiedCString()); |
| 359 } | 345 } |
| 360 Disassembler::Disassemble(ic_stub_code.EntryPoint(), | 346 Disassembler::Disassemble(ic_stub_code.EntryPoint(), |
| 361 ic_stub_code.EntryPoint() + assembler.CodeSize()); | 347 ic_stub_code.EntryPoint() + assembler.CodeSize()); |
| 362 OS::Print("}\n"); | 348 OS::Print("}\n"); |
| 363 } | 349 } |
| 364 | 350 |
| 365 ICData ic_data(ic_stub_code); | |
| 366 ic_data.SetICDataArray(1, classes.length()); | |
| 367 ASSERT(classes.length() == targets.length()); | |
| 368 for (intptr_t i = 0; i < classes.length(); i++) { | |
| 369 GrowableArray<const Class*> temp_classes; | |
| 370 temp_classes.Add(classes[i]); | |
| 371 ic_data.SetCheckAt(i, temp_classes, *(targets[i])); | |
| 372 } | |
| 373 return ic_stub_code.raw(); | 351 return ic_stub_code.raw(); |
| 374 #undef __ | 352 #undef __ |
| 375 } | 353 } |
| 376 | 354 |
| 377 | 355 |
| 378 } // namespace dart | 356 } // namespace dart |
| 379 | 357 |
| 380 #endif // defined TARGET_ARCH_IA32 | 358 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |