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" // 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/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
11 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
12 #include "vm/locations.h" | 12 #include "vm/locations.h" |
13 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
14 #include "vm/parser.h" | 14 #include "vm/parser.h" |
15 #include "vm/stack_frame.h" | 15 #include "vm/stack_frame.h" |
16 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
17 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
18 | 18 |
19 #define __ compiler->assembler()-> | 19 #define __ compiler->assembler()-> |
20 | 20 |
21 namespace dart { | 21 namespace dart { |
22 | 22 |
23 DECLARE_FLAG(int, optimization_counter_threshold); | 23 DECLARE_FLAG(int, optimization_counter_threshold); |
24 DECLARE_FLAG(bool, propagate_ic_data); | 24 DECLARE_FLAG(bool, propagate_ic_data); |
25 DECLARE_FLAG(bool, use_osr); | 25 DECLARE_FLAG(bool, use_osr); |
26 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 26 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
27 DECLARE_FLAG(bool, use_slow_path); | |
27 | 28 |
28 // Generic summary for call instructions that have all arguments pushed | 29 // Generic summary for call instructions that have all arguments pushed |
29 // on the stack and return the result in a fixed register EAX. | 30 // on the stack and return the result in a fixed register EAX. |
30 LocationSummary* Instruction::MakeCallSummary() { | 31 LocationSummary* Instruction::MakeCallSummary() { |
31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 32 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
32 result->set_out(Location::RegisterLocation(EAX)); | 33 result->set_out(Location::RegisterLocation(EAX)); |
33 return result; | 34 return result; |
34 } | 35 } |
35 | 36 |
36 | 37 |
(...skipping 2211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2248 kInstantiateTypeArgumentsRuntimeEntry, | 2249 kInstantiateTypeArgumentsRuntimeEntry, |
2249 2, | 2250 2, |
2250 locs()); | 2251 locs()); |
2251 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 2252 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
2252 __ popl(result_reg); // Pop instantiated type arguments. | 2253 __ popl(result_reg); // Pop instantiated type arguments. |
2253 __ Bind(&type_arguments_instantiated); | 2254 __ Bind(&type_arguments_instantiated); |
2254 } | 2255 } |
2255 | 2256 |
2256 | 2257 |
2257 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { | 2258 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { |
2259 if (opt) { | |
2260 const intptr_t kNumInputs = 0; | |
2261 const intptr_t kNumTemps = 3; | |
2262 LocationSummary* locs = new LocationSummary( | |
2263 kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | |
2264 locs->set_temp(0, Location::RegisterLocation(EAX)); | |
2265 locs->set_temp(1, Location::RegisterLocation(ECX)); | |
2266 locs->set_temp(2, Location::RegisterLocation(EBX)); | |
2267 locs->set_out(Location::RegisterLocation(EAX)); | |
regis
2014/02/28 18:07:01
Don't you miss a return locs here?
Florian Schneider
2014/03/03 11:42:58
Thanks. Yes of course. That should improve the cod
| |
2268 } | |
2258 const intptr_t kNumInputs = 0; | 2269 const intptr_t kNumInputs = 0; |
2259 const intptr_t kNumTemps = 1; | 2270 const intptr_t kNumTemps = 1; |
2260 LocationSummary* locs = | 2271 LocationSummary* locs = |
2261 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2272 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
2262 locs->set_temp(0, Location::RegisterLocation(EDX)); | 2273 locs->set_temp(0, Location::RegisterLocation(EDX)); |
2263 locs->set_out(Location::RegisterLocation(EAX)); | 2274 locs->set_out(Location::RegisterLocation(EAX)); |
2264 return locs; | 2275 return locs; |
2265 } | 2276 } |
2266 | 2277 |
2267 | 2278 |
2279 class AllocateContextSlowPath : public SlowPathCode { | |
2280 public: | |
2281 explicit AllocateContextSlowPath(AllocateContextInstr* instruction) | |
2282 : instruction_(instruction) { } | |
2283 | |
2284 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2285 __ Comment("AllocateContextSlowPath"); | |
2286 __ Bind(entry_label()); | |
2287 | |
2288 LocationSummary* locs = instruction_->locs(); | |
2289 locs->live_registers()->Remove(locs->out()); | |
2290 | |
2291 compiler->SaveLiveRegisters(locs); | |
2292 | |
2293 __ movl(EDX, Immediate(instruction_->num_context_variables())); | |
2294 const ExternalLabel label("alloc_context", | |
2295 StubCode::AllocateContextEntryPoint()); | |
2296 compiler->GenerateCall(instruction_->token_pos(), | |
2297 &label, | |
2298 PcDescriptors::kOther, | |
2299 locs); | |
2300 ASSERT(instruction_->locs()->out().reg() == EAX); | |
2301 compiler->RestoreLiveRegisters(instruction_->locs()); | |
2302 __ jmp(exit_label()); | |
2303 } | |
2304 | |
2305 private: | |
2306 AllocateContextInstr* instruction_; | |
2307 }; | |
2308 | |
2309 | |
2310 | |
2268 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2311 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2312 if (compiler->is_optimizing()) { | |
2313 // Try allocate the object. | |
2314 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this); | |
2315 compiler->AddSlowPathCode(slow_path); | |
2316 intptr_t instance_size = Context::InstanceSize(num_context_variables()); | |
2317 __ movl(EBX, Immediate(instance_size)); | |
regis
2014/02/28 18:07:01
If you were using temp 2 instead of EBX directly,
Florian Schneider
2014/03/03 11:42:58
Done. Changed to temp0, temp1, result, etc.
| |
2318 Isolate* isolate = Isolate::Current(); | |
2319 Heap* heap = isolate->heap(); | |
2320 __ movl(EAX, Address::Absolute(heap->TopAddress())); | |
regis
2014/02/28 18:07:01
ditto
Florian Schneider
2014/03/03 11:42:58
Done.
| |
2321 __ addl(EBX, EAX); | |
regis
2014/02/28 18:07:01
ditto
Florian Schneider
2014/03/03 11:42:58
Done.
| |
2322 // Check if the allocation fits into the remaining space. | |
2323 // EAX: potential new object. | |
2324 // EBX: potential next object start. | |
2325 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | |
2326 if (FLAG_use_slow_path) { | |
2327 __ jmp(slow_path->entry_label()); | |
2328 } else { | |
2329 __ j(ABOVE_EQUAL, slow_path->entry_label()); | |
2330 } | |
2331 | |
2332 // Successfully allocated the object, now update top to point to | |
2333 // next object start and initialize the object. | |
2334 // EAX: new object. | |
2335 // EBX: next object start. | |
2336 // EDX: number of context variables. | |
2337 __ movl(Address::Absolute(heap->TopAddress()), EBX); | |
2338 __ addl(EAX, Immediate(kHeapObjectTag)); | |
2339 __ UpdateAllocationStatsWithSize(kContextCid, instance_size, kNoRegister); | |
2340 | |
2341 // Calculate the size tag and write tags. | |
2342 intptr_t size_tag = (instance_size > RawObject::SizeTag::kMaxSizeTag) | |
2343 ? 0 : instance_size << (RawObject::kSizeTagBit - kObjectAlignmentLog2); | |
2344 | |
2345 intptr_t tags = size_tag | RawObject::ClassIdTag::encode(kContextCid); | |
2346 __ movl(FieldAddress(EAX, Context::tags_offset()), Immediate(tags)); | |
2347 | |
2348 // Setup up number of context variables field. | |
2349 // EAX: new object. | |
2350 __ movl(FieldAddress(EAX, Context::num_variables_offset()), | |
2351 Immediate(num_context_variables())); | |
2352 | |
2353 // Setup isolate field. | |
2354 __ movl(FieldAddress(EAX, Context::isolate_offset()), | |
2355 Immediate(reinterpret_cast<int32_t>(isolate))); | |
2356 | |
2357 // Setup the parent field. | |
2358 const Immediate& raw_null = | |
2359 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
2360 __ movl(FieldAddress(EAX, Context::parent_offset()), raw_null); | |
2361 | |
2362 // Initialize the context variables. | |
2363 // EAX: new object. | |
2364 if (num_context_variables() > 0) { | |
2365 Label loop; | |
2366 __ leal(EBX, FieldAddress(EAX, Context::variable_offset(0))); | |
2367 __ movl(ECX, Immediate(num_context_variables())); | |
2368 __ Bind(&loop); | |
2369 __ decl(ECX); | |
2370 __ movl(Address(EBX, ECX, TIMES_4, 0), raw_null); | |
2371 __ j(NOT_ZERO, &loop, Assembler::kNearJump); | |
2372 } | |
2373 // EAX: new object. | |
2374 __ Bind(slow_path->exit_label()); | |
2375 return; | |
2376 } | |
2377 | |
2269 ASSERT(locs()->temp(0).reg() == EDX); | 2378 ASSERT(locs()->temp(0).reg() == EDX); |
2270 ASSERT(locs()->out().reg() == EAX); | 2379 ASSERT(locs()->out().reg() == EAX); |
2271 | 2380 |
2272 __ movl(EDX, Immediate(num_context_variables())); | 2381 __ movl(EDX, Immediate(num_context_variables())); |
2273 const ExternalLabel label("alloc_context", | 2382 const ExternalLabel label("alloc_context", |
2274 StubCode::AllocateContextEntryPoint()); | 2383 StubCode::AllocateContextEntryPoint()); |
2275 compiler->GenerateCall(token_pos(), | 2384 compiler->GenerateCall(token_pos(), |
2276 &label, | 2385 &label, |
2277 PcDescriptors::kOther, | 2386 PcDescriptors::kOther, |
2278 locs()); | 2387 locs()); |
(...skipping 3096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5375 PcDescriptors::kOther, | 5484 PcDescriptors::kOther, |
5376 locs()); | 5485 locs()); |
5377 __ Drop(ArgumentCount()); // Discard arguments. | 5486 __ Drop(ArgumentCount()); // Discard arguments. |
5378 } | 5487 } |
5379 | 5488 |
5380 } // namespace dart | 5489 } // namespace dart |
5381 | 5490 |
5382 #undef __ | 5491 #undef __ |
5383 | 5492 |
5384 #endif // defined TARGET_ARCH_IA32 | 5493 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |