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

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 182303005: Inline context allocation in optimized code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
« runtime/vm/assembler_ia32.cc ('K') | « runtime/vm/assembler_ia32.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 33158)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -24,6 +24,7 @@
DECLARE_FLAG(bool, propagate_ic_data);
DECLARE_FLAG(bool, use_osr);
DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
+DECLARE_FLAG(bool, use_slow_path);
// Generic summary for call instructions that have all arguments pushed
// on the stack and return the result in a fixed register EAX.
@@ -2255,6 +2256,16 @@
LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const {
+ if (opt) {
+ const intptr_t kNumInputs = 0;
+ const intptr_t kNumTemps = 2;
+ LocationSummary* locs = new LocationSummary(
+ kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
+ locs->set_temp(0, Location::RegisterLocation(ECX));
+ locs->set_temp(1, Location::RegisterLocation(EBX));
+ locs->set_out(Location::RegisterLocation(EAX));
+ return locs;
+ }
const intptr_t kNumInputs = 0;
const intptr_t kNumTemps = 1;
LocationSummary* locs =
@@ -2265,7 +2276,108 @@
}
+class AllocateContextSlowPath : public SlowPathCode {
+ public:
+ explicit AllocateContextSlowPath(AllocateContextInstr* instruction)
+ : instruction_(instruction) { }
+
+ virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+ __ Comment("AllocateContextSlowPath");
+ __ Bind(entry_label());
+
+ LocationSummary* locs = instruction_->locs();
+ locs->live_registers()->Remove(locs->out());
+
+ compiler->SaveLiveRegisters(locs);
+
+ __ movl(EDX, Immediate(instruction_->num_context_variables()));
+ const ExternalLabel label("alloc_context",
+ StubCode::AllocateContextEntryPoint());
+ compiler->GenerateCall(instruction_->token_pos(),
+ &label,
+ PcDescriptors::kOther,
+ locs);
+ ASSERT(instruction_->locs()->out().reg() == EAX);
+ compiler->RestoreLiveRegisters(instruction_->locs());
+ __ jmp(exit_label());
+ }
+
+ private:
+ AllocateContextInstr* instruction_;
+};
+
+
+
void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (compiler->is_optimizing()) {
+ Register temp0 = locs()->temp(0).reg();
+ Register temp1 = locs()->temp(1).reg();
+ Register result = locs()->out().reg();
+ // Try allocate the object.
+ AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this);
+ compiler->AddSlowPathCode(slow_path);
+ intptr_t instance_size = Context::InstanceSize(num_context_variables());
+ __ movl(temp1, Immediate(instance_size));
+ Isolate* isolate = Isolate::Current();
+ Heap* heap = isolate->heap();
+ __ movl(result, Address::Absolute(heap->TopAddress()));
+ __ addl(temp1, result);
+ // Check if the allocation fits into the remaining space.
+ // EAX: potential new object.
+ // EBX: potential next object start.
+ __ cmpl(temp1, Address::Absolute(heap->EndAddress()));
+ if (FLAG_use_slow_path) {
+ __ jmp(slow_path->entry_label());
+ } else {
+ __ j(ABOVE_EQUAL, slow_path->entry_label());
+ }
+
+ // Successfully allocated the object, now update top to point to
+ // next object start and initialize the object.
+ // EAX: new object.
+ // EBX: next object start.
+ // EDX: number of context variables.
+ __ movl(Address::Absolute(heap->TopAddress()), temp1);
+ __ addl(result, Immediate(kHeapObjectTag));
+ __ UpdateAllocationStatsWithSize(kContextCid, instance_size, kNoRegister);
+
+ // Calculate the size tag and write tags.
+ intptr_t size_tag = (instance_size > RawObject::SizeTag::kMaxSizeTag)
+ ? 0 : instance_size << (RawObject::kSizeTagBit - kObjectAlignmentLog2);
+
+ intptr_t tags = size_tag | RawObject::ClassIdTag::encode(kContextCid);
+ __ movl(FieldAddress(result, Context::tags_offset()), Immediate(tags));
+
+ // Setup up number of context variables field.
+ // EAX: new object.
+ __ movl(FieldAddress(result, Context::num_variables_offset()),
+ Immediate(num_context_variables()));
+
+ // Setup isolate field.
+ __ movl(FieldAddress(result, Context::isolate_offset()),
+ Immediate(reinterpret_cast<int32_t>(isolate)));
+
+ // Setup the parent field.
+ const Immediate& raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ __ movl(FieldAddress(result, Context::parent_offset()), raw_null);
+
+ // Initialize the context variables.
+ // EAX: new object.
+ if (num_context_variables() > 0) {
+ Label loop;
+ __ leal(temp1, FieldAddress(result, Context::variable_offset(0)));
+ __ movl(temp0, Immediate(num_context_variables()));
+ __ Bind(&loop);
+ __ decl(temp0);
+ __ movl(Address(temp1, temp0, TIMES_4, 0), raw_null);
+ __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+ }
+ // EAX: new object.
+ __ Bind(slow_path->exit_label());
+ return;
+ }
+
ASSERT(locs()->temp(0).reg() == EDX);
ASSERT(locs()->out().reg() == EAX);
« runtime/vm/assembler_ia32.cc ('K') | « runtime/vm/assembler_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698