Chromium Code Reviews| 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 |