Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(528)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 346823003: VM: Optimized context allocation on all platforms. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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.h" 11 #include "vm/flow_graph.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/locations.h" 13 #include "vm/locations.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/parser.h" 15 #include "vm/parser.h"
16 #include "vm/stack_frame.h" 16 #include "vm/stack_frame.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/symbols.h" 18 #include "vm/symbols.h"
19 19
20 #define __ compiler->assembler()-> 20 #define __ compiler->assembler()->
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DECLARE_FLAG(bool, emit_edge_counters); 24 DECLARE_FLAG(bool, emit_edge_counters);
25 DECLARE_FLAG(int, optimization_counter_threshold); 25 DECLARE_FLAG(int, optimization_counter_threshold);
26 DECLARE_FLAG(bool, propagate_ic_data); 26 DECLARE_FLAG(bool, propagate_ic_data);
27 DECLARE_FLAG(bool, use_osr); 27 DECLARE_FLAG(bool, use_osr);
28 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); 28 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
29 DECLARE_FLAG(bool, use_slow_path);
30 29
31 // Generic summary for call instructions that have all arguments pushed 30 // Generic summary for call instructions that have all arguments pushed
32 // on the stack and return the result in a fixed register EAX. 31 // on the stack and return the result in a fixed register EAX.
33 LocationSummary* Instruction::MakeCallSummary() { 32 LocationSummary* Instruction::MakeCallSummary() {
34 Isolate* isolate = Isolate::Current(); 33 Isolate* isolate = Isolate::Current();
35 LocationSummary* result = new(isolate) LocationSummary( 34 LocationSummary* result = new(isolate) LocationSummary(
36 isolate, 0, 0, LocationSummary::kCall); 35 isolate, 0, 0, LocationSummary::kCall);
37 result->set_out(0, Location::RegisterLocation(EAX)); 36 result->set_out(0, Location::RegisterLocation(EAX));
38 return result; 37 return result;
39 } 38 }
(...skipping 1994 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); 2033 isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
2035 locs->set_in(0, Location::RegisterLocation(ECX)); 2034 locs->set_in(0, Location::RegisterLocation(ECX));
2036 locs->set_in(1, Location::RegisterLocation(EDX)); 2035 locs->set_in(1, Location::RegisterLocation(EDX));
2037 locs->set_out(0, Location::RegisterLocation(EAX)); 2036 locs->set_out(0, Location::RegisterLocation(EAX));
2038 return locs; 2037 return locs;
2039 } 2038 }
2040 2039
2041 2040
2042 // Inlines array allocation for known constant values. 2041 // Inlines array allocation for known constant values.
2043 static void InlineArrayAllocation(FlowGraphCompiler* compiler, 2042 static void InlineArrayAllocation(FlowGraphCompiler* compiler,
2044 intptr_t num_elements, 2043 intptr_t num_elements,
2045 Label* slow_path, 2044 Label* slow_path,
2046 Label* done) { 2045 Label* done) {
2047 const Register kLengthReg = EDX; 2046 const Register kLengthReg = EDX;
2048 const Register kElemTypeReg = ECX; 2047 const Register kElemTypeReg = ECX;
2049 const intptr_t kArraySize = Array::InstanceSize(num_elements); 2048 const intptr_t instance_size = Array::InstanceSize(num_elements);
2050 Isolate* isolate = Isolate::Current();
2051 Heap* heap = isolate->heap();
2052 2049
2053 __ movl(EAX, Address::Absolute(heap->TopAddress())); 2050 // Instance in EAX.
2054 __ movl(EBX, EAX); 2051 // Object end address in EBX.
2055 2052 __ TryAllocateArray(kArrayCid, instance_size, slow_path, Assembler::kFarJump,
2056 __ addl(EBX, Immediate(kArraySize)); 2053 EAX, // instance
2057 __ j(CARRY, slow_path); 2054 EBX); // end address
2058
2059 // Check if the allocation fits into the remaining space.
2060 // EAX: potential new object start.
2061 // EBX: potential next object start.
2062 __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
2063 __ j(ABOVE_EQUAL, slow_path);
2064
2065 // Successfully allocated the object(s), now update top to point to
2066 // next object start and initialize the object.
2067 __ movl(Address::Absolute(heap->TopAddress()), EBX);
2068 __ addl(EAX, Immediate(kHeapObjectTag));
2069 __ UpdateAllocationStatsWithSize(kArrayCid, kArraySize, kNoRegister);
2070
2071 // Initialize the tags.
2072 // EAX: new object start as a tagged pointer.
2073 {
2074 uword tags = 0;
2075 tags = RawObject::ClassIdTag::update(kArrayCid, tags);
2076 tags = RawObject::SizeTag::update(kArraySize, tags);
2077 __ movl(FieldAddress(EAX, Array::tags_offset()), Immediate(tags));
2078 }
2079 2055
2080 // Store the type argument field. 2056 // Store the type argument field.
2081 __ StoreIntoObjectNoBarrier(EAX, 2057 __ StoreIntoObjectNoBarrier(EAX,
2082 FieldAddress(EAX, Array::type_arguments_offset()), 2058 FieldAddress(EAX, Array::type_arguments_offset()),
2083 kElemTypeReg); 2059 kElemTypeReg);
2084 2060
2085 // Set the length field. 2061 // Set the length field.
2086 __ StoreIntoObjectNoBarrier(EAX, 2062 __ StoreIntoObjectNoBarrier(EAX,
2087 FieldAddress(EAX, Array::length_offset()), 2063 FieldAddress(EAX, Array::length_offset()),
2088 kLengthReg); 2064 kLengthReg);
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2370 deopt_id(), 2346 deopt_id(),
2371 kInstantiateTypeArgumentsRuntimeEntry, 2347 kInstantiateTypeArgumentsRuntimeEntry,
2372 2, 2348 2,
2373 locs()); 2349 locs());
2374 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 2350 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
2375 __ popl(result_reg); // Pop instantiated type arguments. 2351 __ popl(result_reg); // Pop instantiated type arguments.
2376 __ Bind(&type_arguments_instantiated); 2352 __ Bind(&type_arguments_instantiated);
2377 } 2353 }
2378 2354
2379 2355
2380 LocationSummary* AllocateContextInstr::MakeLocationSummary(Isolate* isolate, 2356 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
2381 bool opt) const { 2357 Isolate* isolate,
2382 if (opt) { 2358 bool opt) const {
2383 const intptr_t kNumInputs = 0; 2359 ASSERT(opt);
2384 const intptr_t kNumTemps = 2;
2385 LocationSummary* locs = new(isolate) LocationSummary(
2386 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
2387 locs->set_temp(0, Location::RegisterLocation(ECX));
2388 locs->set_temp(1, Location::RegisterLocation(EBX));
2389 locs->set_out(0, Location::RegisterLocation(EAX));
2390 return locs;
2391 }
2392 const intptr_t kNumInputs = 0; 2360 const intptr_t kNumInputs = 0;
2393 const intptr_t kNumTemps = 1; 2361 const intptr_t kNumTemps = 1;
2394 LocationSummary* locs = new(isolate) LocationSummary( 2362 LocationSummary* locs = new(isolate) LocationSummary(
2395 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); 2363 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
2396 locs->set_temp(0, Location::RegisterLocation(EDX)); 2364 locs->set_temp(0, Location::RegisterLocation(ECX));
2397 locs->set_out(0, Location::RegisterLocation(EAX)); 2365 locs->set_out(0, Location::RegisterLocation(EAX));
2398 return locs; 2366 return locs;
2399 } 2367 }
2400 2368
2401 2369
2402 class AllocateContextSlowPath : public SlowPathCode { 2370 class AllocateContextSlowPath : public SlowPathCode {
2403 public: 2371 public:
2404 explicit AllocateContextSlowPath(AllocateContextInstr* instruction) 2372 explicit AllocateContextSlowPath(
2373 AllocateUninitializedContextInstr* instruction)
2405 : instruction_(instruction) { } 2374 : instruction_(instruction) { }
2406 2375
2407 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2376 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2408 __ Comment("AllocateContextSlowPath"); 2377 __ Comment("AllocateContextSlowPath");
2409 __ Bind(entry_label()); 2378 __ Bind(entry_label());
2410 2379
2411 LocationSummary* locs = instruction_->locs(); 2380 LocationSummary* locs = instruction_->locs();
2412 ASSERT(!locs->live_registers()->Contains(locs->out(0))); 2381 ASSERT(!locs->live_registers()->Contains(locs->out(0)));
2413 2382
2414 compiler->SaveLiveRegisters(locs); 2383 compiler->SaveLiveRegisters(locs);
2415 2384
2416 __ movl(EDX, Immediate(instruction_->num_context_variables())); 2385 __ movl(EDX, Immediate(instruction_->num_context_variables()));
2417 StubCode* stub_code = compiler->isolate()->stub_code(); 2386 StubCode* stub_code = compiler->isolate()->stub_code();
2418 const ExternalLabel label(stub_code->AllocateContextEntryPoint()); 2387 const ExternalLabel label(stub_code->AllocateContextEntryPoint());
2419 compiler->GenerateCall(instruction_->token_pos(), 2388 compiler->GenerateCall(instruction_->token_pos(),
2420 &label, 2389 &label,
2421 RawPcDescriptors::kOther, 2390 RawPcDescriptors::kOther,
2422 locs); 2391 locs);
2423 ASSERT(instruction_->locs()->out(0).reg() == EAX); 2392 ASSERT(instruction_->locs()->out(0).reg() == EAX);
2424 compiler->RestoreLiveRegisters(instruction_->locs()); 2393 compiler->RestoreLiveRegisters(instruction_->locs());
2425 __ jmp(exit_label()); 2394 __ jmp(exit_label());
2426 } 2395 }
2427 2396
2428 private: 2397 private:
2429 AllocateContextInstr* instruction_; 2398 AllocateUninitializedContextInstr* instruction_;
2430 }; 2399 };
2431 2400
2432 2401
2402 void AllocateUninitializedContextInstr::EmitNativeCode(
2403 FlowGraphCompiler* compiler) {
2404 ASSERT(compiler->is_optimizing());
2405 Register temp = locs()->temp(0).reg();
2406 Register result = locs()->out(0).reg();
2407 // Try allocate the object.
2408 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this);
2409 compiler->AddSlowPathCode(slow_path);
2410 intptr_t instance_size = Context::InstanceSize(num_context_variables());
2411
2412 __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
2413 Assembler::kFarJump,
2414 result, // instance
2415 temp); // end address
2416
2417 // Setup up number of context variables field.
2418 __ movl(FieldAddress(result, Context::num_variables_offset()),
2419 Immediate(num_context_variables()));
2420
2421 // Setup isolate field.
2422 __ movl(FieldAddress(result, Context::isolate_offset()),
2423 Immediate(reinterpret_cast<int32_t>(Isolate::Current())));
2424
2425 __ Bind(slow_path->exit_label());
2426 }
2427
2428
2429 LocationSummary* AllocateContextInstr::MakeLocationSummary(Isolate* isolate,
2430 bool opt) const {
2431 const intptr_t kNumInputs = 0;
2432 const intptr_t kNumTemps = 1;
2433 LocationSummary* locs = new(isolate) LocationSummary(
2434 isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
2435 locs->set_temp(0, Location::RegisterLocation(EDX));
2436 locs->set_out(0, Location::RegisterLocation(EAX));
2437 return locs;
2438 }
2439
2433 2440
2434 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2441 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2435 if (compiler->is_optimizing()) {
2436 Register temp0 = locs()->temp(0).reg();
2437 Register temp1 = locs()->temp(1).reg();
2438 Register result = locs()->out(0).reg();
2439 // Try allocate the object.
2440 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this);
2441 compiler->AddSlowPathCode(slow_path);
2442 intptr_t instance_size = Context::InstanceSize(num_context_variables());
2443 __ movl(temp1, Immediate(instance_size));
2444 Isolate* isolate = Isolate::Current();
2445 Heap* heap = isolate->heap();
2446 __ movl(result, Address::Absolute(heap->TopAddress()));
2447 __ addl(temp1, result);
2448 // Check if the allocation fits into the remaining space.
2449 // EAX: potential new object.
2450 // EBX: potential next object start.
2451 __ cmpl(temp1, Address::Absolute(heap->EndAddress()));
2452 if (FLAG_use_slow_path) {
2453 __ jmp(slow_path->entry_label());
2454 } else {
2455 __ j(ABOVE_EQUAL, slow_path->entry_label());
2456 }
2457
2458 // Successfully allocated the object, now update top to point to
2459 // next object start and initialize the object.
2460 // EAX: new object.
2461 // EBX: next object start.
2462 // EDX: number of context variables.
2463 __ movl(Address::Absolute(heap->TopAddress()), temp1);
2464 __ addl(result, Immediate(kHeapObjectTag));
2465 __ UpdateAllocationStatsWithSize(kContextCid, instance_size, kNoRegister);
2466
2467 // Calculate the size tag and write tags.
2468 intptr_t size_tag = (instance_size > RawObject::SizeTag::kMaxSizeTag)
2469 ? 0 : instance_size << (RawObject::kSizeTagPos - kObjectAlignmentLog2);
2470
2471 intptr_t tags = size_tag | RawObject::ClassIdTag::encode(kContextCid);
2472 __ movl(FieldAddress(result, Context::tags_offset()), Immediate(tags));
2473
2474 // Setup up number of context variables field.
2475 // EAX: new object.
2476 __ movl(FieldAddress(result, Context::num_variables_offset()),
2477 Immediate(num_context_variables()));
2478
2479 // Setup isolate field.
2480 __ movl(FieldAddress(result, Context::isolate_offset()),
2481 Immediate(reinterpret_cast<int32_t>(isolate)));
2482
2483 // Setup the parent field.
2484 const Immediate& raw_null =
2485 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2486 __ movl(FieldAddress(result, Context::parent_offset()), raw_null);
2487
2488 // Initialize the context variables.
2489 // EAX: new object.
2490 if (num_context_variables() > 0) {
2491 Label loop;
2492 __ leal(temp1, FieldAddress(result, Context::variable_offset(0)));
2493 __ movl(temp0, Immediate(num_context_variables()));
2494 __ Bind(&loop);
2495 __ decl(temp0);
2496 __ movl(Address(temp1, temp0, TIMES_4, 0), raw_null);
2497 __ j(NOT_ZERO, &loop, Assembler::kNearJump);
2498 }
2499 // EAX: new object.
2500 __ Bind(slow_path->exit_label());
2501 return;
2502 }
2503
2504 ASSERT(locs()->temp(0).reg() == EDX); 2442 ASSERT(locs()->temp(0).reg() == EDX);
2505 ASSERT(locs()->out(0).reg() == EAX); 2443 ASSERT(locs()->out(0).reg() == EAX);
2506 2444
2507 __ movl(EDX, Immediate(num_context_variables())); 2445 __ movl(EDX, Immediate(num_context_variables()));
2508 StubCode* stub_code = compiler->isolate()->stub_code(); 2446 StubCode* stub_code = compiler->isolate()->stub_code();
2509 const ExternalLabel label(stub_code->AllocateContextEntryPoint()); 2447 const ExternalLabel label(stub_code->AllocateContextEntryPoint());
2510 compiler->GenerateCall(token_pos(), 2448 compiler->GenerateCall(token_pos(),
2511 &label, 2449 &label,
2512 RawPcDescriptors::kOther, 2450 RawPcDescriptors::kOther,
2513 locs()); 2451 locs());
(...skipping 4042 matching lines...) Expand 10 before | Expand all | Expand 10 after
6556 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6494 __ movl(EDX, Immediate(kInvalidObjectPointer));
6557 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6495 __ movl(EDX, Immediate(kInvalidObjectPointer));
6558 #endif 6496 #endif
6559 } 6497 }
6560 6498
6561 } // namespace dart 6499 } // namespace dart
6562 6500
6563 #undef __ 6501 #undef __
6564 6502
6565 #endif // defined TARGET_ARCH_IA32 6503 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698