| 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 = 2; | 
|  | 2262     LocationSummary* locs = new LocationSummary( | 
|  | 2263         kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | 
|  | 2264     locs->set_temp(0, Location::RegisterLocation(ECX)); | 
|  | 2265     locs->set_temp(1, Location::RegisterLocation(EBX)); | 
|  | 2266     locs->set_out(Location::RegisterLocation(EAX)); | 
|  | 2267     return locs; | 
|  | 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     Register temp0 = locs()->temp(0).reg(); | 
|  | 2314     Register temp1 = locs()->temp(1).reg(); | 
|  | 2315     Register result = locs()->out().reg(); | 
|  | 2316     // Try allocate the object. | 
|  | 2317     AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this); | 
|  | 2318     compiler->AddSlowPathCode(slow_path); | 
|  | 2319     intptr_t instance_size = Context::InstanceSize(num_context_variables()); | 
|  | 2320     __ movl(temp1, Immediate(instance_size)); | 
|  | 2321     Isolate* isolate = Isolate::Current(); | 
|  | 2322     Heap* heap = isolate->heap(); | 
|  | 2323     __ movl(result, Address::Absolute(heap->TopAddress())); | 
|  | 2324     __ addl(temp1, result); | 
|  | 2325     // Check if the allocation fits into the remaining space. | 
|  | 2326     // EAX: potential new object. | 
|  | 2327     // EBX: potential next object start. | 
|  | 2328     __ cmpl(temp1, Address::Absolute(heap->EndAddress())); | 
|  | 2329     if (FLAG_use_slow_path) { | 
|  | 2330       __ jmp(slow_path->entry_label()); | 
|  | 2331     } else { | 
|  | 2332       __ j(ABOVE_EQUAL, slow_path->entry_label()); | 
|  | 2333     } | 
|  | 2334 | 
|  | 2335     // Successfully allocated the object, now update top to point to | 
|  | 2336     // next object start and initialize the object. | 
|  | 2337     // EAX: new object. | 
|  | 2338     // EBX: next object start. | 
|  | 2339     // EDX: number of context variables. | 
|  | 2340     __ movl(Address::Absolute(heap->TopAddress()), temp1); | 
|  | 2341     __ addl(result, Immediate(kHeapObjectTag)); | 
|  | 2342     __ UpdateAllocationStatsWithSize(kContextCid, instance_size, kNoRegister); | 
|  | 2343 | 
|  | 2344     // Calculate the size tag and write tags. | 
|  | 2345     intptr_t size_tag = (instance_size > RawObject::SizeTag::kMaxSizeTag) | 
|  | 2346         ? 0 : instance_size << (RawObject::kSizeTagBit - kObjectAlignmentLog2); | 
|  | 2347 | 
|  | 2348     intptr_t tags = size_tag | RawObject::ClassIdTag::encode(kContextCid); | 
|  | 2349     __ movl(FieldAddress(result, Context::tags_offset()), Immediate(tags)); | 
|  | 2350 | 
|  | 2351     // Setup up number of context variables field. | 
|  | 2352     // EAX: new object. | 
|  | 2353     __ movl(FieldAddress(result, Context::num_variables_offset()), | 
|  | 2354             Immediate(num_context_variables())); | 
|  | 2355 | 
|  | 2356     // Setup isolate field. | 
|  | 2357     __ movl(FieldAddress(result, Context::isolate_offset()), | 
|  | 2358             Immediate(reinterpret_cast<int32_t>(isolate))); | 
|  | 2359 | 
|  | 2360     // Setup the parent field. | 
|  | 2361     const Immediate& raw_null = | 
|  | 2362         Immediate(reinterpret_cast<intptr_t>(Object::null())); | 
|  | 2363     __ movl(FieldAddress(result, Context::parent_offset()), raw_null); | 
|  | 2364 | 
|  | 2365     // Initialize the context variables. | 
|  | 2366     // EAX: new object. | 
|  | 2367     if (num_context_variables() > 0) { | 
|  | 2368       Label loop; | 
|  | 2369       __ leal(temp1, FieldAddress(result, Context::variable_offset(0))); | 
|  | 2370       __ movl(temp0, Immediate(num_context_variables())); | 
|  | 2371       __ Bind(&loop); | 
|  | 2372       __ decl(temp0); | 
|  | 2373       __ movl(Address(temp1, temp0, TIMES_4, 0), raw_null); | 
|  | 2374       __ j(NOT_ZERO, &loop, Assembler::kNearJump); | 
|  | 2375     } | 
|  | 2376     // EAX: new object. | 
|  | 2377     __ Bind(slow_path->exit_label()); | 
|  | 2378     return; | 
|  | 2379   } | 
|  | 2380 | 
| 2269   ASSERT(locs()->temp(0).reg() == EDX); | 2381   ASSERT(locs()->temp(0).reg() == EDX); | 
| 2270   ASSERT(locs()->out().reg() == EAX); | 2382   ASSERT(locs()->out().reg() == EAX); | 
| 2271 | 2383 | 
| 2272   __ movl(EDX, Immediate(num_context_variables())); | 2384   __ movl(EDX, Immediate(num_context_variables())); | 
| 2273   const ExternalLabel label("alloc_context", | 2385   const ExternalLabel label("alloc_context", | 
| 2274                             StubCode::AllocateContextEntryPoint()); | 2386                             StubCode::AllocateContextEntryPoint()); | 
| 2275   compiler->GenerateCall(token_pos(), | 2387   compiler->GenerateCall(token_pos(), | 
| 2276                          &label, | 2388                          &label, | 
| 2277                          PcDescriptors::kOther, | 2389                          PcDescriptors::kOther, | 
| 2278                          locs()); | 2390                          locs()); | 
| (...skipping 3096 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5375                          PcDescriptors::kOther, | 5487                          PcDescriptors::kOther, | 
| 5376                          locs()); | 5488                          locs()); | 
| 5377   __ Drop(ArgumentCount());  // Discard arguments. | 5489   __ Drop(ArgumentCount());  // Discard arguments. | 
| 5378 } | 5490 } | 
| 5379 | 5491 | 
| 5380 }  // namespace dart | 5492 }  // namespace dart | 
| 5381 | 5493 | 
| 5382 #undef __ | 5494 #undef __ | 
| 5383 | 5495 | 
| 5384 #endif  // defined TARGET_ARCH_IA32 | 5496 #endif  // defined TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|