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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 148153010: Synchronize with r15701. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/simulator-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); 154 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
155 __ Push(Smi::FromInt(StackFrame::STUB)); 155 __ Push(Smi::FromInt(StackFrame::STUB));
156 // Adjust FP to point to saved FP. 156 // Adjust FP to point to saved FP.
157 __ add(fp, sp, Operand(2 * kPointerSize)); 157 __ add(fp, sp, Operand(2 * kPointerSize));
158 } else { 158 } else {
159 PredictableCodeSizeScope predictible_code_size_scope( 159 PredictableCodeSizeScope predictible_code_size_scope(
160 masm_, kNoCodeAgeSequenceLength * Assembler::kInstrSize); 160 masm_, kNoCodeAgeSequenceLength * Assembler::kInstrSize);
161 // The following three instructions must remain together and unmodified 161 // The following three instructions must remain together and unmodified
162 // for code aging to work properly. 162 // for code aging to work properly.
163 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); 163 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
164 // Load undefined value here, so the value is ready for the loop 164 __ nop(ip.code());
165 // below.
166 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
167 // Adjust FP to point to saved FP. 165 // Adjust FP to point to saved FP.
168 __ add(fp, sp, Operand(2 * kPointerSize)); 166 __ add(fp, sp, Operand(2 * kPointerSize));
169 } 167 }
170 frame_is_built_ = true; 168 frame_is_built_ = true;
171 info_->AddNoFrameRange(0, masm_->pc_offset()); 169 info_->AddNoFrameRange(0, masm_->pc_offset());
172 } 170 }
173 171
174 // Reserve space for the stack slots needed by the code. 172 // Reserve space for the stack slots needed by the code.
175 int slots = GetStackSlotCount(); 173 int slots = GetStackSlotCount();
176 if (slots > 0) { 174 if (slots > 0) {
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) + 334 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) +
337 deopt_jump_table_.length() * 7)) { 335 deopt_jump_table_.length() * 7)) {
338 Abort("Generated code is too large"); 336 Abort("Generated code is too large");
339 } 337 }
340 338
341 if (deopt_jump_table_.length() > 0) { 339 if (deopt_jump_table_.length() > 0) {
342 Comment(";;; -------------------- Jump table --------------------"); 340 Comment(";;; -------------------- Jump table --------------------");
343 } 341 }
344 Label table_start; 342 Label table_start;
345 __ bind(&table_start); 343 __ bind(&table_start);
346 Label needs_frame_not_call; 344 Label needs_frame;
347 Label needs_frame_is_call;
348 for (int i = 0; i < deopt_jump_table_.length(); i++) { 345 for (int i = 0; i < deopt_jump_table_.length(); i++) {
349 __ bind(&deopt_jump_table_[i].label); 346 __ bind(&deopt_jump_table_[i].label);
350 Address entry = deopt_jump_table_[i].address; 347 Address entry = deopt_jump_table_[i].address;
351 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; 348 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type;
352 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 349 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
353 if (id == Deoptimizer::kNotDeoptimizationEntry) { 350 if (id == Deoptimizer::kNotDeoptimizationEntry) {
354 Comment(";;; jump table entry %d.", i); 351 Comment(";;; jump table entry %d.", i);
355 } else { 352 } else {
356 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); 353 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
357 } 354 }
358 if (deopt_jump_table_[i].needs_frame) { 355 if (deopt_jump_table_[i].needs_frame) {
359 __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry))); 356 __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry)));
360 if (type == Deoptimizer::LAZY) { 357 if (needs_frame.is_bound()) {
361 if (needs_frame_is_call.is_bound()) { 358 __ b(&needs_frame);
362 __ b(&needs_frame_is_call);
363 } else {
364 __ bind(&needs_frame_is_call);
365 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
366 // This variant of deopt can only be used with stubs. Since we don't
367 // have a function pointer to install in the stack frame that we're
368 // building, install a special marker there instead.
369 ASSERT(info()->IsStub());
370 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
371 __ push(scratch0());
372 __ add(fp, sp, Operand(2 * kPointerSize));
373 __ mov(lr, Operand(pc), LeaveCC, al);
374 __ mov(pc, ip);
375 }
376 } else { 359 } else {
377 if (needs_frame_not_call.is_bound()) { 360 __ bind(&needs_frame);
378 __ b(&needs_frame_not_call); 361 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
379 } else { 362 // This variant of deopt can only be used with stubs. Since we don't
380 __ bind(&needs_frame_not_call); 363 // have a function pointer to install in the stack frame that we're
381 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); 364 // building, install a special marker there instead.
382 // This variant of deopt can only be used with stubs. Since we don't 365 ASSERT(info()->IsStub());
383 // have a function pointer to install in the stack frame that we're 366 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
384 // building, install a special marker there instead. 367 __ push(scratch0());
385 ASSERT(info()->IsStub()); 368 __ add(fp, sp, Operand(2 * kPointerSize));
386 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); 369 __ mov(lr, Operand(pc), LeaveCC, al);
387 __ push(scratch0()); 370 __ mov(pc, ip);
388 __ add(fp, sp, Operand(2 * kPointerSize));
389 __ mov(pc, ip);
390 }
391 } 371 }
392 } else { 372 } else {
393 if (type == Deoptimizer::LAZY) { 373 __ mov(lr, Operand(pc), LeaveCC, al);
394 __ mov(lr, Operand(pc), LeaveCC, al); 374 __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry)));
395 __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry)));
396 } else {
397 __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry)));
398 }
399 } 375 }
400 masm()->CheckConstPool(false, false); 376 masm()->CheckConstPool(false, false);
401 } 377 }
402 378
403 // Force constant pool emission at the end of the deopt jump table to make 379 // Force constant pool emission at the end of the deopt jump table to make
404 // sure that no constant pools are emitted after. 380 // sure that no constant pools are emitted after.
405 masm()->CheckConstPool(true, false); 381 masm()->CheckConstPool(true, false);
406 382
407 // The deoptimization jump table is the last part of the instruction 383 // The deoptimization jump table is the last part of the instruction
408 // sequence. Mark the generated code as done unless we bailed out. 384 // sequence. Mark the generated code as done unless we bailed out.
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 763 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
788 if (entry == NULL) { 764 if (entry == NULL) {
789 Abort("bailout was not prepared"); 765 Abort("bailout was not prepared");
790 return; 766 return;
791 } 767 }
792 768
793 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. 769 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM.
794 if (FLAG_deopt_every_n_times == 1 && 770 if (FLAG_deopt_every_n_times == 1 &&
795 !info()->IsStub() && 771 !info()->IsStub() &&
796 info()->opt_count() == id) { 772 info()->opt_count() == id) {
797 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); 773 ASSERT(frame_is_built_);
774 __ Call(entry, RelocInfo::RUNTIME_ENTRY);
798 return; 775 return;
799 } 776 }
800 777
801 if (FLAG_trap_on_deopt && info()->IsOptimizing()) { 778 if (FLAG_trap_on_deopt && info()->IsOptimizing()) {
802 __ stop("trap_on_deopt", cc); 779 __ stop("trap_on_deopt", cc);
803 } 780 }
804 781
805 ASSERT(info()->IsStub() || frame_is_built_); 782 ASSERT(info()->IsStub() || frame_is_built_);
806 bool needs_lazy_deopt = info()->IsStub();
807 if (cc == al && frame_is_built_) { 783 if (cc == al && frame_is_built_) {
808 if (needs_lazy_deopt) { 784 __ Call(entry, RelocInfo::RUNTIME_ENTRY);
809 __ Call(entry, RelocInfo::RUNTIME_ENTRY);
810 } else {
811 __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
812 }
813 } else { 785 } else {
814 // We often have several deopts to the same entry, reuse the last 786 // We often have several deopts to the same entry, reuse the last
815 // jump entry if this is the case. 787 // jump entry if this is the case.
816 if (deopt_jump_table_.is_empty() || 788 if (deopt_jump_table_.is_empty() ||
817 (deopt_jump_table_.last().address != entry) || 789 (deopt_jump_table_.last().address != entry) ||
818 (deopt_jump_table_.last().bailout_type != bailout_type) || 790 (deopt_jump_table_.last().bailout_type != bailout_type) ||
819 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) { 791 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) {
820 Deoptimizer::JumpTableEntry table_entry(entry, 792 Deoptimizer::JumpTableEntry table_entry(entry,
821 bailout_type, 793 bailout_type,
822 !frame_is_built_); 794 !frame_is_built_);
(...skipping 4510 matching lines...) Expand 10 before | Expand all | Expand 10 after
5333 if (!instr->hydrogen()->CanOmitPrototypeChecks()) { 5305 if (!instr->hydrogen()->CanOmitPrototypeChecks()) {
5334 for (int i = 0; i < prototypes->length(); i++) { 5306 for (int i = 0; i < prototypes->length(); i++) {
5335 __ LoadHeapObject(prototype_reg, prototypes->at(i)); 5307 __ LoadHeapObject(prototype_reg, prototypes->at(i));
5336 __ ldr(map_reg, FieldMemOperand(prototype_reg, HeapObject::kMapOffset)); 5308 __ ldr(map_reg, FieldMemOperand(prototype_reg, HeapObject::kMapOffset));
5337 DoCheckMapCommon(map_reg, maps->at(i), instr->environment()); 5309 DoCheckMapCommon(map_reg, maps->at(i), instr->environment());
5338 } 5310 }
5339 } 5311 }
5340 } 5312 }
5341 5313
5342 5314
5343 void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
5344 class DeferredAllocateObject: public LDeferredCode {
5345 public:
5346 DeferredAllocateObject(LCodeGen* codegen, LAllocateObject* instr)
5347 : LDeferredCode(codegen), instr_(instr) { }
5348 virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
5349 virtual LInstruction* instr() { return instr_; }
5350 private:
5351 LAllocateObject* instr_;
5352 };
5353
5354 DeferredAllocateObject* deferred =
5355 new(zone()) DeferredAllocateObject(this, instr);
5356
5357 Register result = ToRegister(instr->result());
5358 Register scratch = ToRegister(instr->temp());
5359 Register scratch2 = ToRegister(instr->temp2());
5360 Handle<JSFunction> constructor = instr->hydrogen()->constructor();
5361 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
5362 int instance_size = initial_map->instance_size();
5363 ASSERT(initial_map->pre_allocated_property_fields() +
5364 initial_map->unused_property_fields() -
5365 initial_map->inobject_properties() == 0);
5366
5367 __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(),
5368 TAG_OBJECT);
5369
5370 __ bind(deferred->exit());
5371 if (FLAG_debug_code) {
5372 Label is_in_new_space;
5373 __ JumpIfInNewSpace(result, scratch, &is_in_new_space);
5374 __ Abort("Allocated object is not in new-space");
5375 __ bind(&is_in_new_space);
5376 }
5377
5378 // Load the initial map.
5379 Register map = scratch;
5380 __ LoadHeapObject(map, constructor);
5381 __ ldr(map, FieldMemOperand(map, JSFunction::kPrototypeOrInitialMapOffset));
5382
5383 // Initialize map and fields of the newly allocated object.
5384 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
5385 __ str(map, FieldMemOperand(result, JSObject::kMapOffset));
5386 __ LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex);
5387 __ str(scratch, FieldMemOperand(result, JSObject::kElementsOffset));
5388 __ str(scratch, FieldMemOperand(result, JSObject::kPropertiesOffset));
5389 if (initial_map->inobject_properties() != 0) {
5390 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
5391 for (int i = 0; i < initial_map->inobject_properties(); i++) {
5392 int property_offset = JSObject::kHeaderSize + i * kPointerSize;
5393 __ str(scratch, FieldMemOperand(result, property_offset));
5394 }
5395 }
5396 }
5397
5398
5399 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
5400 Register result = ToRegister(instr->result());
5401 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
5402 int instance_size = initial_map->instance_size();
5403
5404 // TODO(3095996): Get rid of this. For now, we need to make the
5405 // result register contain a valid pointer because it is already
5406 // contained in the register pointer map.
5407 __ mov(result, Operand::Zero());
5408
5409 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
5410 __ mov(r0, Operand(Smi::FromInt(instance_size)));
5411 __ push(r0);
5412 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
5413 __ StoreToSafepointRegisterSlot(r0, result);
5414 }
5415
5416
5417 void LCodeGen::DoAllocate(LAllocate* instr) { 5315 void LCodeGen::DoAllocate(LAllocate* instr) {
5418 class DeferredAllocate: public LDeferredCode { 5316 class DeferredAllocate: public LDeferredCode {
5419 public: 5317 public:
5420 DeferredAllocate(LCodeGen* codegen, LAllocate* instr) 5318 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5421 : LDeferredCode(codegen), instr_(instr) { } 5319 : LDeferredCode(codegen), instr_(instr) { }
5422 virtual void Generate() { codegen()->DoDeferredAllocate(instr_); } 5320 virtual void Generate() { codegen()->DoDeferredAllocate(instr_); }
5423 virtual LInstruction* instr() { return instr_; } 5321 virtual LInstruction* instr() { return instr_; }
5424 private: 5322 private:
5425 LAllocate* instr_; 5323 LAllocate* instr_;
5426 }; 5324 };
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
5896 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5794 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5897 __ ldr(result, FieldMemOperand(scratch, 5795 __ ldr(result, FieldMemOperand(scratch,
5898 FixedArray::kHeaderSize - kPointerSize)); 5796 FixedArray::kHeaderSize - kPointerSize));
5899 __ bind(&done); 5797 __ bind(&done);
5900 } 5798 }
5901 5799
5902 5800
5903 #undef __ 5801 #undef __
5904 5802
5905 } } // namespace v8::internal 5803 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/simulator-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698