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

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

Issue 145773008: A64: Synchronize with r17104. (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/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 19 matching lines...) Expand all
30 #include "a64/lithium-codegen-a64.h" 30 #include "a64/lithium-codegen-a64.h"
31 #include "a64/lithium-gap-resolver-a64.h" 31 #include "a64/lithium-gap-resolver-a64.h"
32 #include "code-stubs.h" 32 #include "code-stubs.h"
33 #include "stub-cache.h" 33 #include "stub-cache.h"
34 #include "hydrogen-osr.h" 34 #include "hydrogen-osr.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 39
40 class SafepointGenerator : public CallWrapper { 40 class SafepointGenerator V8_FINAL : public CallWrapper {
41 public: 41 public:
42 SafepointGenerator(LCodeGen* codegen, 42 SafepointGenerator(LCodeGen* codegen,
43 LPointerMap* pointers, 43 LPointerMap* pointers,
44 Safepoint::DeoptMode mode) 44 Safepoint::DeoptMode mode)
45 : codegen_(codegen), 45 : codegen_(codegen),
46 pointers_(pointers), 46 pointers_(pointers),
47 deopt_mode_(mode) { } 47 deopt_mode_(mode) { }
48 virtual ~SafepointGenerator() { } 48 virtual ~SafepointGenerator() { }
49 49
50 virtual void BeforeCall(int call_size) const { } 50 virtual void BeforeCall(int call_size) const { }
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 RelocInfo::Mode mode, 405 RelocInfo::Mode mode,
406 LInstruction* instr) { 406 LInstruction* instr) {
407 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); 407 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
408 } 408 }
409 409
410 410
411 void LCodeGen::CallCodeGeneric(Handle<Code> code, 411 void LCodeGen::CallCodeGeneric(Handle<Code> code,
412 RelocInfo::Mode mode, 412 RelocInfo::Mode mode,
413 LInstruction* instr, 413 LInstruction* instr,
414 SafepointMode safepoint_mode) { 414 SafepointMode safepoint_mode) {
415 EnsureSpaceForLazyDeopt(); 415 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
416 ASSERT(instr != NULL); 416 ASSERT(instr != NULL);
417 417
418 Assembler::BlockConstPoolScope scope(masm_); 418 Assembler::BlockConstPoolScope scope(masm_);
419 LPointerMap* pointers = instr->pointer_map(); 419 LPointerMap* pointers = instr->pointer_map();
420 RecordPosition(pointers->position()); 420 RecordPosition(pointers->position());
421 __ Call(code, mode); 421 __ Call(code, mode);
422 RecordSafepointWithLazyDeopt(instr, safepoint_mode); 422 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
423 423
424 if ((code->kind() == Code::BINARY_OP_IC) || 424 if ((code->kind() == Code::BINARY_OP_IC) ||
425 (code->kind() == Code::COMPARE_IC)) { 425 (code->kind() == Code::COMPARE_IC)) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); 498 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
499 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 499 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
500 } 500 }
501 501
502 ASSERT(ToRegister(instr->result()).is(x0)); 502 ASSERT(ToRegister(instr->result()).is(x0));
503 } 503 }
504 504
505 505
506 void LCodeGen::CallRuntime(const Runtime::Function* function, 506 void LCodeGen::CallRuntime(const Runtime::Function* function,
507 int num_arguments, 507 int num_arguments,
508 LInstruction* instr) { 508 LInstruction* instr,
509 SaveFPRegsMode save_doubles) {
509 ASSERT(instr != NULL); 510 ASSERT(instr != NULL);
510 LPointerMap* pointers = instr->pointer_map(); 511 LPointerMap* pointers = instr->pointer_map();
511 ASSERT(pointers != NULL); 512 ASSERT(pointers != NULL);
512 RecordPosition(pointers->position()); 513 RecordPosition(pointers->position());
513 514
514 __ CallRuntime(function, num_arguments); 515 __ CallRuntime(function, num_arguments, save_doubles);
516
515 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 517 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
516 } 518 }
517 519
518 520
519 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 521 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
520 int argc, 522 int argc,
521 LInstruction* instr) { 523 LInstruction* instr) {
522 __ CallRuntimeSaveDoubles(id); 524 __ CallRuntimeSaveDoubles(id);
523 RecordSafepointWithRegisters( 525 RecordSafepointWithRegisters(
524 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 526 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 osr_pc_offset_ = masm()->pc_offset(); 743 osr_pc_offset_ = masm()->pc_offset();
742 744
743 // Adjust the frame size, subsuming the unoptimized frame into the 745 // Adjust the frame size, subsuming the unoptimized frame into the
744 // optimized frame. 746 // optimized frame.
745 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 747 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
746 ASSERT(slots >= 0); 748 ASSERT(slots >= 0);
747 __ Claim(slots); 749 __ Claim(slots);
748 } 750 }
749 751
750 752
751 bool LCodeGen::GenerateBody() {
752 ASSERT(is_generating());
753 bool emit_instructions = true;
754
755 for (current_instruction_ = 0;
756 !is_aborted() && (current_instruction_ < instructions_->length());
757 current_instruction_++) {
758 LInstruction* instr = instructions_->at(current_instruction_);
759
760 // Don't emit code for basic blocks with a replacement.
761 if (instr->IsLabel()) {
762 emit_instructions = !LLabel::cast(instr)->HasReplacement();
763 }
764 if (!emit_instructions) continue;
765
766 if (FLAG_code_comments && instr->HasInterestingComment(this)) {
767 Comment(";;; <@%d,#%d> %s",
768 current_instruction_,
769 instr->hydrogen_value()->id(),
770 instr->Mnemonic());
771 }
772
773 RecordAndUpdatePosition(instr->position());
774
775 instr->CompileToNative(this);
776 }
777 EnsureSpaceForLazyDeopt();
778 last_lazy_deopt_pc_ = masm()->pc_offset();
779 return !is_aborted();
780 }
781
782
783 bool LCodeGen::GenerateDeferredCode() { 753 bool LCodeGen::GenerateDeferredCode() {
784 ASSERT(is_generating()); 754 ASSERT(is_generating());
785 if (deferred_.length() > 0) { 755 if (deferred_.length() > 0) {
786 for (int i = 0; !is_aborted() && (i < deferred_.length()); i++) { 756 for (int i = 0; !is_aborted() && (i < deferred_.length()); i++) {
787 LDeferredCode* code = deferred_[i]; 757 LDeferredCode* code = deferred_[i];
788 758
789 int pos = instructions_->at(code->instruction_index())->position(); 759 int pos = instructions_->at(code->instruction_index())->position();
790 RecordAndUpdatePosition(pos); 760 RecordAndUpdatePosition(pos);
791 761
792 Comment(";;; <@%d,#%d> " 762 Comment(";;; <@%d,#%d> "
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 info()->CommitDependencies(code); 835 info()->CommitDependencies(code);
866 } 836 }
867 837
868 838
869 void LCodeGen::Abort(BailoutReason reason) { 839 void LCodeGen::Abort(BailoutReason reason) {
870 info()->set_bailout_reason(reason); 840 info()->set_bailout_reason(reason);
871 status_ = ABORTED; 841 status_ = ABORTED;
872 } 842 }
873 843
874 844
875 void LCodeGen::Comment(const char* format, ...) {
876 if (!FLAG_code_comments) return;
877 char buffer[4 * KB];
878 StringBuilder builder(buffer, ARRAY_SIZE(buffer));
879 va_list arguments;
880 va_start(arguments, format);
881 builder.AddFormattedList(format, arguments);
882 va_end(arguments);
883
884 // Copy the string before recording it in the assembler to avoid
885 // issues when the stack allocated buffer goes out of scope.
886 size_t length = builder.position();
887 Vector<char> copy = Vector<char>::New(length + 1);
888 memcpy(copy.start(), builder.Finalize(), copy.length());
889 masm()->RecordComment(copy.start());
890 }
891
892
893 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 845 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
894 ZoneList<Handle<Map> > maps(1, zone()); 846 ZoneList<Handle<Map> > maps(1, zone());
847 ZoneList<Handle<JSObject> > objects(1, zone());
895 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 848 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
896 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 849 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
897 RelocInfo::Mode mode = it.rinfo()->rmode(); 850 if (Code::IsWeakEmbeddedObject(code->kind(), it.rinfo()->target_object())) {
898 if (mode == RelocInfo::EMBEDDED_OBJECT && 851 if (it.rinfo()->target_object()->IsMap()) {
899 it.rinfo()->target_object()->IsMap()) { 852 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
900 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
901 if (map->CanTransition()) {
902 maps.Add(map, zone()); 853 maps.Add(map, zone());
854 } else if (it.rinfo()->target_object()->IsJSObject()) {
855 Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
856 objects.Add(object, zone());
903 } 857 }
904 } 858 }
905 } 859 }
906 #ifdef VERIFY_HEAP 860 #ifdef VERIFY_HEAP
907 // This disables verification of weak embedded maps after full GC. 861 // This disables verification of weak embedded objects after full GC.
908 // AddDependentCode can cause a GC, which would observe the state where 862 // AddDependentCode can cause a GC, which would observe the state where
909 // this code is not yet in the depended code lists of the embedded maps. 863 // this code is not yet in the depended code lists of the embedded maps.
910 NoWeakEmbeddedMapsVerificationScope disable_verification_of_embedded_maps; 864 NoWeakObjectVerificationScope disable_verification_of_embedded_objects;
911 #endif 865 #endif
912 for (int i = 0; i < maps.length(); i++) { 866 for (int i = 0; i < maps.length(); i++) {
913 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code); 867 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code);
914 } 868 }
869 for (int i = 0; i < objects.length(); i++) {
870 AddWeakObjectToCodeDependency(isolate()->heap(), objects.at(i), code);
871 }
915 } 872 }
916 873
917 874
918 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 875 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
919 int length = deoptimizations_.length(); 876 int length = deoptimizations_.length();
920 if (length == 0) return; 877 if (length == 0) return;
921 878
922 Handle<DeoptimizationInputData> data = 879 Handle<DeoptimizationInputData> data =
923 factory()->NewDeoptimizationInputData(length, TENURED); 880 factory()->NewDeoptimizationInputData(length, TENURED);
924 881
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 void LCodeGen::DeoptimizeIfNotRoot(Register rt, 1033 void LCodeGen::DeoptimizeIfNotRoot(Register rt,
1077 Heap::RootListIndex index, 1034 Heap::RootListIndex index,
1078 LEnvironment* environment) { 1035 LEnvironment* environment) {
1079 Label dont_deopt; 1036 Label dont_deopt;
1080 __ JumpIfRoot(rt, index, &dont_deopt); 1037 __ JumpIfRoot(rt, index, &dont_deopt);
1081 Deoptimize(environment); 1038 Deoptimize(environment);
1082 __ Bind(&dont_deopt); 1039 __ Bind(&dont_deopt);
1083 } 1040 }
1084 1041
1085 1042
1086 void LCodeGen::EnsureSpaceForLazyDeopt() { 1043 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
1087 if (info()->IsStub()) return; 1044 if (info()->IsStub()) return;
1088 // Ensure that we have enough space after the previous lazy-bailout 1045 // Ensure that we have enough space after the previous lazy-bailout
1089 // instruction for patching the code here. 1046 // instruction for patching the code here.
1090 intptr_t current_pc = masm()->pc_offset(); 1047 intptr_t current_pc = masm()->pc_offset();
1091 int patch_size = Deoptimizer::patch_size();
1092 1048
1093 if (current_pc < (last_lazy_deopt_pc_ + patch_size)) { 1049 if (current_pc < (last_lazy_deopt_pc_ + space_needed)) {
1094 intptr_t padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; 1050 ptrdiff_t padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
1095 ASSERT((padding_size % kInstructionSize) == 0); 1051 ASSERT((padding_size % kInstructionSize) == 0);
1096 InstructionAccurateScope instruction_accurate( 1052 InstructionAccurateScope instruction_accurate(
1097 masm(), padding_size / kInstructionSize); 1053 masm(), padding_size / kInstructionSize);
1098 1054
1099 while (padding_size > 0) { 1055 while (padding_size > 0) {
1100 __ nop(); 1056 __ nop();
1101 padding_size -= kInstructionSize; 1057 padding_size -= kInstructionSize;
1102 } 1058 }
1103 } 1059 }
1104 } 1060 }
(...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 __ Ldr(temp, FieldMemOperand(temp, Cell::kValueOffset)); 2407 __ Ldr(temp, FieldMemOperand(temp, Cell::kValueOffset));
2452 __ Cmp(reg, temp); 2408 __ Cmp(reg, temp);
2453 } else { 2409 } else {
2454 __ Cmp(reg, Operand(object)); 2410 __ Cmp(reg, Operand(object));
2455 } 2411 }
2456 DeoptimizeIf(ne, instr->environment()); 2412 DeoptimizeIf(ne, instr->environment());
2457 } 2413 }
2458 2414
2459 2415
2460 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { 2416 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
2461 EnsureSpaceForLazyDeopt(); 2417 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
2462 last_lazy_deopt_pc_ = masm()->pc_offset(); 2418 last_lazy_deopt_pc_ = masm()->pc_offset();
2463 ASSERT(instr->HasEnvironment()); 2419 ASSERT(instr->HasEnvironment());
2464 LEnvironment* env = instr->environment(); 2420 LEnvironment* env = instr->environment();
2465 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 2421 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
2466 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 2422 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
2467 } 2423 }
2468 2424
2469 2425
2470 void LCodeGen::DoDateField(LDateField* instr) { 2426 void LCodeGen::DoDateField(LDateField* instr) {
2471 Register object = ToRegister(instr->date()); 2427 Register object = ToRegister(instr->date());
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
2805 } 2761 }
2806 2762
2807 2763
2808 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 2764 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
2809 Register global = ToRegister(instr->global_object()); 2765 Register global = ToRegister(instr->global_object());
2810 Register result = ToRegister(instr->result()); 2766 Register result = ToRegister(instr->result());
2811 __ Ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); 2767 __ Ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
2812 } 2768 }
2813 2769
2814 2770
2815 int LCodeGen::GetNextEmittedBlock() const {
2816 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
2817 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
2818 }
2819 return -1;
2820 }
2821
2822
2823 void LCodeGen::EmitGoto(int block) { 2771 void LCodeGen::EmitGoto(int block) {
2824 // Do not emit jump if we are emitting a goto to the next block. 2772 // Do not emit jump if we are emitting a goto to the next block.
2825 if (!IsNextEmittedBlock(block)) { 2773 if (!IsNextEmittedBlock(block)) {
2826 __ B(chunk_->GetAssemblyLabel(LookupDestination(block))); 2774 __ B(chunk_->GetAssemblyLabel(LookupDestination(block)));
2827 } 2775 }
2828 } 2776 }
2829 2777
2830 2778
2831 void LCodeGen::DoGoto(LGoto* instr) { 2779 void LCodeGen::DoGoto(LGoto* instr) {
2832 EmitGoto(instr->block_id()); 2780 EmitGoto(instr->block_id());
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
3504 } 3452 }
3505 3453
3506 3454
3507 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 3455 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
3508 HObjectAccess access = instr->hydrogen()->access(); 3456 HObjectAccess access = instr->hydrogen()->access();
3509 int offset = access.offset(); 3457 int offset = access.offset();
3510 Register object = ToRegister(instr->object()); 3458 Register object = ToRegister(instr->object());
3511 3459
3512 if (access.IsExternalMemory()) { 3460 if (access.IsExternalMemory()) {
3513 Register result = ToRegister(instr->result()); 3461 Register result = ToRegister(instr->result());
3514 __ Ldr(result, MemOperand(object, offset)); 3462 // TODO(all): Does this need an Integer32 accessor?
3463 if (access.representation().IsByte()) {
3464 __ Ldrb(result, MemOperand(object, offset));
3465 } else {
3466 __ Ldr(result, MemOperand(object, offset));
3467 }
3515 return; 3468 return;
3516 } 3469 }
3517 3470
3518 if (instr->hydrogen()->representation().IsDouble()) { 3471 if (instr->hydrogen()->representation().IsDouble()) {
3519 FPRegister result = ToDoubleRegister(instr->result()); 3472 FPRegister result = ToDoubleRegister(instr->result());
3520 __ Ldr(result, FieldMemOperand(object, offset)); 3473 __ Ldr(result, FieldMemOperand(object, offset));
3474 return;
3475 }
3476
3477 Register result = ToRegister(instr->result());
3478 Register source;
3479 if (access.IsInobject()) {
3480 source = object;
3521 } else { 3481 } else {
3522 Register result = ToRegister(instr->result()); 3482 // Load the properties array, using result as a scratch register.
3523 Register src = no_reg; 3483 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
3524 if (access.IsInobject()) { 3484 source = result;
3525 src = object; 3485 }
3526 } else { 3486 if (access.representation().IsByte()) {
3527 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 3487 __ Ldrb(result, FieldMemOperand(source, offset));
3528 src = result; 3488 } else if (access.representation().IsInteger32()) {
3529 } 3489 __ Ldr(result.W(), FieldMemOperand(source, offset));
3530 if (access.representation().IsInteger32()) { 3490 } else {
3531 __ Ldr(result.W(), FieldMemOperand(src, offset)); 3491 __ Ldr(result, FieldMemOperand(source, offset));
3532 } else {
3533 __ Ldr(result, FieldMemOperand(src, offset));
3534 }
3535 } 3492 }
3536 } 3493 }
3537 3494
3538 3495
3539 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 3496 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3540 // LoadIC expects x2 to hold the name, and x0 to hold the receiver. 3497 // LoadIC expects x2 to hold the name, and x0 to hold the receiver.
3541 ASSERT(ToRegister(instr->object()).is(x0)); 3498 ASSERT(ToRegister(instr->object()).is(x0));
3542 __ Mov(x2, Operand(instr->name())); 3499 __ Mov(x2, Operand(instr->name()));
3543 3500
3544 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3501 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after
4676 // Perform stack overflow check. 4633 // Perform stack overflow check.
4677 Label done; 4634 Label done;
4678 __ CompareRoot(masm()->StackPointer(), Heap::kStackLimitRootIndex); 4635 __ CompareRoot(masm()->StackPointer(), Heap::kStackLimitRootIndex);
4679 __ B(hs, &done); 4636 __ B(hs, &done);
4680 4637
4681 // TODO(bafsa): Make sure that the EnsureSpaceForLazyDeopt inside 4638 // TODO(bafsa): Make sure that the EnsureSpaceForLazyDeopt inside
4682 // CallCodeGeneric will not insert any nop while calling the stub by 4639 // CallCodeGeneric will not insert any nop while calling the stub by
4683 // inserting them now. The EnsureSpaceForLazyDeopt in CallCodeGeneric 4640 // inserting them now. The EnsureSpaceForLazyDeopt in CallCodeGeneric
4684 // will go away at some point during the rebase (r18642) so this will become 4641 // will go away at some point during the rebase (r18642) so this will become
4685 // unecessary and should be removed at this point. 4642 // unecessary and should be removed at this point.
4686 EnsureSpaceForLazyDeopt(); 4643 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
4687 4644
4688 PredictableCodeSizeScope predictable(masm_, 4645 PredictableCodeSizeScope predictable(masm_,
4689 Assembler::kCallSizeWithRelocation); 4646 Assembler::kCallSizeWithRelocation);
4690 CallCode(isolate()->builtins()->StackCheck(), 4647 CallCode(isolate()->builtins()->StackCheck(),
4691 RelocInfo::CODE_TARGET, 4648 RelocInfo::CODE_TARGET,
4692 instr); 4649 instr);
4693 EnsureSpaceForLazyDeopt(); 4650 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
4694 last_lazy_deopt_pc_ = masm()->pc_offset(); 4651 last_lazy_deopt_pc_ = masm()->pc_offset();
4695 4652
4696 __ Bind(&done); 4653 __ Bind(&done);
4697 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 4654 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
4698 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 4655 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
4699 } else { 4656 } else {
4700 ASSERT(instr->hydrogen()->is_backwards_branch()); 4657 ASSERT(instr->hydrogen()->is_backwards_branch());
4701 // Perform stack overflow check if this goto needs it before jumping. 4658 // Perform stack overflow check if this goto needs it before jumping.
4702 DeferredStackCheck* deferred_stack_check = 4659 DeferredStackCheck* deferred_stack_check =
4703 new(zone()) DeferredStackCheck(this, instr); 4660 new(zone()) DeferredStackCheck(this, instr);
4704 __ CompareRoot(masm()->StackPointer(), Heap::kStackLimitRootIndex); 4661 __ CompareRoot(masm()->StackPointer(), Heap::kStackLimitRootIndex);
4705 __ B(lo, deferred_stack_check->entry()); 4662 __ B(lo, deferred_stack_check->entry());
4706 4663
4707 EnsureSpaceForLazyDeopt(); 4664 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
4708 last_lazy_deopt_pc_ = masm()->pc_offset(); 4665 last_lazy_deopt_pc_ = masm()->pc_offset();
4709 __ Bind(instr->done_label()); 4666 __ Bind(instr->done_label());
4710 deferred_stack_check->SetExit(instr->done_label()); 4667 deferred_stack_check->SetExit(instr->done_label());
4711 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 4668 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
4712 // Don't record a deoptimization index for the safepoint here. 4669 // Don't record a deoptimization index for the safepoint here.
4713 // This will be done explicitly when emitting call and the safepoint in 4670 // This will be done explicitly when emitting call and the safepoint in
4714 // the deferred code. 4671 // the deferred code.
4715 } 4672 }
4716 } 4673 }
4717 4674
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
4946 Representation representation = instr->representation(); 4903 Representation representation = instr->representation();
4947 4904
4948 Register object = ToRegister(instr->object()); 4905 Register object = ToRegister(instr->object());
4949 Register temp0 = ToRegister(instr->temp0()); 4906 Register temp0 = ToRegister(instr->temp0());
4950 Register temp1 = ToRegister(instr->temp1()); 4907 Register temp1 = ToRegister(instr->temp1());
4951 HObjectAccess access = instr->hydrogen()->access(); 4908 HObjectAccess access = instr->hydrogen()->access();
4952 int offset = access.offset(); 4909 int offset = access.offset();
4953 4910
4954 if (access.IsExternalMemory()) { 4911 if (access.IsExternalMemory()) {
4955 Register value = ToRegister(instr->value()); 4912 Register value = ToRegister(instr->value());
4956 __ Str(value, MemOperand(object, offset)); 4913 if (representation.IsByte()) {
4914 __ Strb(value, MemOperand(object, offset));
4915 } else {
4916 __ Str(value, MemOperand(object, offset));
4917 }
4957 return; 4918 return;
4958 } 4919 }
4959 4920
4960 Handle<Map> transition = instr->transition(); 4921 Handle<Map> transition = instr->transition();
4961 4922
4962 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 4923 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
4963 Register value = ToRegister(instr->value()); 4924 Register value = ToRegister(instr->value());
4964 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 4925 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4965 DeoptimizeIfSmi(value, instr->environment()); 4926 DeoptimizeIfSmi(value, instr->environment());
4966 } 4927 }
(...skipping 19 matching lines...) Expand all
4986 temp1, 4947 temp1,
4987 GetLinkRegisterState(), 4948 GetLinkRegisterState(),
4988 kSaveFPRegs, 4949 kSaveFPRegs,
4989 OMIT_REMEMBERED_SET, 4950 OMIT_REMEMBERED_SET,
4990 OMIT_SMI_CHECK); 4951 OMIT_SMI_CHECK);
4991 } 4952 }
4992 } 4953 }
4993 4954
4994 // Do the store. 4955 // Do the store.
4995 Register value = ToRegister(instr->value()); 4956 Register value = ToRegister(instr->value());
4996 Register dst = no_reg; 4957 Register destination;
4997 SmiCheck check_needed = 4958 SmiCheck check_needed =
4998 instr->hydrogen()->value()->IsHeapObject() 4959 instr->hydrogen()->value()->IsHeapObject()
4999 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4960 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
5000 if (access.IsInobject()) { 4961 if (access.IsInobject()) {
5001 dst = object; 4962 destination = object;
5002 } else { 4963 } else {
5003 __ Ldr(temp0, FieldMemOperand(object, JSObject::kPropertiesOffset)); 4964 __ Ldr(temp0, FieldMemOperand(object, JSObject::kPropertiesOffset));
5004 dst = temp0; 4965 destination = temp0;
5005 } 4966 }
5006 if (access.representation().IsInteger32()) { 4967 if (representation.IsByte()) {
5007 __ Str(value.W(), FieldMemOperand(dst, offset)); 4968 __ Strb(value, FieldMemOperand(destination, offset));
4969 } else if (access.representation().IsInteger32()) {
4970 __ Str(value.W(), FieldMemOperand(destination, offset));
5008 } else { 4971 } else {
5009 __ Str(value, FieldMemOperand(dst, offset)); 4972 __ Str(value, FieldMemOperand(destination, offset));
5010 } 4973 }
5011 if (instr->hydrogen()->NeedsWriteBarrier()) { 4974 if (instr->hydrogen()->NeedsWriteBarrier()) {
5012 __ RecordWriteField(dst, 4975 __ RecordWriteField(destination,
5013 offset, 4976 offset,
5014 value, // Clobbered. 4977 value, // Clobbered.
5015 temp1, // Clobbered. 4978 temp1, // Clobbered.
5016 GetLinkRegisterState(), 4979 GetLinkRegisterState(),
5017 kSaveFPRegs, 4980 kSaveFPRegs,
5018 EMIT_REMEMBERED_SET, 4981 EMIT_REMEMBERED_SET,
5019 check_needed); 4982 check_needed);
5020 } 4983 }
5021 } 4984 }
5022 4985
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
5597 __ Bind(&out_of_object); 5560 __ Bind(&out_of_object);
5598 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 5561 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
5599 // Index is equal to negated out of object property index plus 1. 5562 // Index is equal to negated out of object property index plus 1.
5600 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 5563 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
5601 __ Ldr(result, FieldMemOperand(result, 5564 __ Ldr(result, FieldMemOperand(result,
5602 FixedArray::kHeaderSize - kPointerSize)); 5565 FixedArray::kHeaderSize - kPointerSize));
5603 __ Bind(&done); 5566 __ Bind(&done);
5604 } 5567 }
5605 5568
5606 } } // namespace v8::internal 5569 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698