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

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 110573004: Merge bleeding_edge 17696:18016. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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 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 3188 matching lines...) Expand 10 before | Expand all | Expand 10 after
3199 testl(result_reg, result_reg); 3199 testl(result_reg, result_reg);
3200 j(not_zero, &done, Label::kNear); 3200 j(not_zero, &done, Label::kNear);
3201 movmskpd(result_reg, xmm0); 3201 movmskpd(result_reg, xmm0);
3202 andl(result_reg, Immediate(1)); 3202 andl(result_reg, Immediate(1));
3203 j(not_zero, lost_precision, dst); 3203 j(not_zero, lost_precision, dst);
3204 } 3204 }
3205 bind(&done); 3205 bind(&done);
3206 } 3206 }
3207 3207
3208 3208
3209 void MacroAssembler::Throw(BailoutReason reason) {
3210 #ifdef DEBUG
3211 const char* msg = GetBailoutReason(reason);
3212 if (msg != NULL) {
3213 RecordComment("Throw message: ");
3214 RecordComment(msg);
3215 }
3216 #endif
3217
3218 push(rax);
3219 Push(Smi::FromInt(reason));
3220 if (!has_frame_) {
3221 // We don't actually want to generate a pile of code for this, so just
3222 // claim there is a stack frame, without generating one.
3223 FrameScope scope(this, StackFrame::NONE);
3224 CallRuntime(Runtime::kThrowMessage, 1);
3225 } else {
3226 CallRuntime(Runtime::kThrowMessage, 1);
3227 }
3228 // Control will not return here.
3229 int3();
3230 }
3231
3232
3233 void MacroAssembler::ThrowIf(Condition cc, BailoutReason reason) {
3234 Label L;
3235 j(NegateCondition(cc), &L);
3236 Throw(reason);
3237 // will not return here
3238 bind(&L);
3239 }
3240
3241
3209 void MacroAssembler::LoadInstanceDescriptors(Register map, 3242 void MacroAssembler::LoadInstanceDescriptors(Register map,
3210 Register descriptors) { 3243 Register descriptors) {
3211 movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 3244 movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset));
3212 } 3245 }
3213 3246
3214 3247
3215 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 3248 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
3216 movq(dst, FieldOperand(map, Map::kBitField3Offset)); 3249 movq(dst, FieldOperand(map, Map::kBitField3Offset));
3217 DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 3250 DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
3218 } 3251 }
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
3899 int token_offset = 3932 int token_offset =
3900 Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize; 3933 Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize;
3901 movq(scratch, FieldOperand(scratch, token_offset)); 3934 movq(scratch, FieldOperand(scratch, token_offset));
3902 cmpq(scratch, FieldOperand(kScratchRegister, token_offset)); 3935 cmpq(scratch, FieldOperand(kScratchRegister, token_offset));
3903 j(not_equal, miss); 3936 j(not_equal, miss);
3904 3937
3905 bind(&same_contexts); 3938 bind(&same_contexts);
3906 } 3939 }
3907 3940
3908 3941
3942 // Compute the hash code from the untagged key. This must be kept in sync with
3943 // ComputeIntegerHash in utils.h and KeyedLoadGenericElementStub in
3944 // code-stub-hydrogen.cc
3909 void MacroAssembler::GetNumberHash(Register r0, Register scratch) { 3945 void MacroAssembler::GetNumberHash(Register r0, Register scratch) {
3910 // First of all we assign the hash seed to scratch. 3946 // First of all we assign the hash seed to scratch.
3911 LoadRoot(scratch, Heap::kHashSeedRootIndex); 3947 LoadRoot(scratch, Heap::kHashSeedRootIndex);
3912 SmiToInteger32(scratch, scratch); 3948 SmiToInteger32(scratch, scratch);
3913 3949
3914 // Xor original key with a seed. 3950 // Xor original key with a seed.
3915 xorl(r0, scratch); 3951 xorl(r0, scratch);
3916 3952
3917 // Compute the hash code from the untagged key. This must be kept in sync 3953 // Compute the hash code from the untagged key. This must be kept in sync
3918 // with ComputeIntegerHash in utils.h. 3954 // with ComputeIntegerHash in utils.h.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3973 Label done; 4009 Label done;
3974 4010
3975 GetNumberHash(r0, r1); 4011 GetNumberHash(r0, r1);
3976 4012
3977 // Compute capacity mask. 4013 // Compute capacity mask.
3978 SmiToInteger32(r1, FieldOperand(elements, 4014 SmiToInteger32(r1, FieldOperand(elements,
3979 SeededNumberDictionary::kCapacityOffset)); 4015 SeededNumberDictionary::kCapacityOffset));
3980 decl(r1); 4016 decl(r1);
3981 4017
3982 // Generate an unrolled loop that performs a few probes before giving up. 4018 // Generate an unrolled loop that performs a few probes before giving up.
3983 const int kProbes = 4; 4019 for (int i = 0; i < kNumberDictionaryProbes; i++) {
3984 for (int i = 0; i < kProbes; i++) {
3985 // Use r2 for index calculations and keep the hash intact in r0. 4020 // Use r2 for index calculations and keep the hash intact in r0.
3986 movq(r2, r0); 4021 movq(r2, r0);
3987 // Compute the masked index: (hash + i + i * i) & mask. 4022 // Compute the masked index: (hash + i + i * i) & mask.
3988 if (i > 0) { 4023 if (i > 0) {
3989 addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 4024 addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i)));
3990 } 4025 }
3991 and_(r2, r1); 4026 and_(r2, r1);
3992 4027
3993 // Scale the index by multiplying by the entry size. 4028 // Scale the index by multiplying by the entry size.
3994 ASSERT(SeededNumberDictionary::kEntrySize == 3); 4029 ASSERT(SeededNumberDictionary::kEntrySize == 3);
3995 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 4030 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
3996 4031
3997 // Check if the key matches. 4032 // Check if the key matches.
3998 cmpq(key, FieldOperand(elements, 4033 cmpq(key, FieldOperand(elements,
3999 r2, 4034 r2,
4000 times_pointer_size, 4035 times_pointer_size,
4001 SeededNumberDictionary::kElementsStartOffset)); 4036 SeededNumberDictionary::kElementsStartOffset));
4002 if (i != (kProbes - 1)) { 4037 if (i != (kNumberDictionaryProbes - 1)) {
4003 j(equal, &done); 4038 j(equal, &done);
4004 } else { 4039 } else {
4005 j(not_equal, miss); 4040 j(not_equal, miss);
4006 } 4041 }
4007 } 4042 }
4008 4043
4009 bind(&done); 4044 bind(&done);
4010 // Check that the value is a normal propety. 4045 // Check that the value is a normal propety.
4011 const int kDetailsOffset = 4046 const int kDetailsOffset =
4012 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 4047 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4074 4109
4075 4110
4076 void MacroAssembler::Allocate(int object_size, 4111 void MacroAssembler::Allocate(int object_size,
4077 Register result, 4112 Register result,
4078 Register result_end, 4113 Register result_end,
4079 Register scratch, 4114 Register scratch,
4080 Label* gc_required, 4115 Label* gc_required,
4081 AllocationFlags flags) { 4116 AllocationFlags flags) {
4082 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4117 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
4083 ASSERT(object_size <= Page::kMaxNonCodeHeapObjectSize); 4118 ASSERT(object_size <= Page::kMaxNonCodeHeapObjectSize);
4084 if (!FLAG_inline_new || 4119 if (!FLAG_inline_new) {
4085 // TODO(mstarzinger): Implement more efficiently by keeping then
4086 // bump-pointer allocation area empty instead of recompiling code.
4087 isolate()->heap_profiler()->is_tracking_allocations()) {
4088 if (emit_debug_code()) { 4120 if (emit_debug_code()) {
4089 // Trash the registers to simulate an allocation failure. 4121 // Trash the registers to simulate an allocation failure.
4090 movl(result, Immediate(0x7091)); 4122 movl(result, Immediate(0x7091));
4091 if (result_end.is_valid()) { 4123 if (result_end.is_valid()) {
4092 movl(result_end, Immediate(0x7191)); 4124 movl(result_end, Immediate(0x7191));
4093 } 4125 }
4094 if (scratch.is_valid()) { 4126 if (scratch.is_valid()) {
4095 movl(scratch, Immediate(0x7291)); 4127 movl(scratch, Immediate(0x7291));
4096 } 4128 }
4097 } 4129 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
4157 } 4189 }
4158 4190
4159 4191
4160 void MacroAssembler::Allocate(Register object_size, 4192 void MacroAssembler::Allocate(Register object_size,
4161 Register result, 4193 Register result,
4162 Register result_end, 4194 Register result_end,
4163 Register scratch, 4195 Register scratch,
4164 Label* gc_required, 4196 Label* gc_required,
4165 AllocationFlags flags) { 4197 AllocationFlags flags) {
4166 ASSERT((flags & SIZE_IN_WORDS) == 0); 4198 ASSERT((flags & SIZE_IN_WORDS) == 0);
4167 if (!FLAG_inline_new || 4199 if (!FLAG_inline_new) {
4168 // TODO(mstarzinger): Implement more efficiently by keeping then
4169 // bump-pointer allocation area empty instead of recompiling code.
4170 isolate()->heap_profiler()->is_tracking_allocations()) {
4171 if (emit_debug_code()) { 4200 if (emit_debug_code()) {
4172 // Trash the registers to simulate an allocation failure. 4201 // Trash the registers to simulate an allocation failure.
4173 movl(result, Immediate(0x7091)); 4202 movl(result, Immediate(0x7091));
4174 movl(result_end, Immediate(0x7191)); 4203 movl(result_end, Immediate(0x7191));
4175 if (scratch.is_valid()) { 4204 if (scratch.is_valid()) {
4176 movl(scratch, Immediate(0x7291)); 4205 movl(scratch, Immediate(0x7291));
4177 } 4206 }
4178 // object_size is left unchanged by this function. 4207 // object_size is left unchanged by this function.
4179 } 4208 }
4180 jmp(gc_required); 4209 jmp(gc_required);
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
4628 const int kMinimumStackSlots = kRegisterPassedArguments; 4657 const int kMinimumStackSlots = kRegisterPassedArguments;
4629 if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; 4658 if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots;
4630 return num_arguments; 4659 return num_arguments;
4631 #else 4660 #else
4632 if (num_arguments < kRegisterPassedArguments) return 0; 4661 if (num_arguments < kRegisterPassedArguments) return 0;
4633 return num_arguments - kRegisterPassedArguments; 4662 return num_arguments - kRegisterPassedArguments;
4634 #endif 4663 #endif
4635 } 4664 }
4636 4665
4637 4666
4667 void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
4668 Register index,
4669 Register value,
4670 uint32_t encoding_mask) {
4671 Label is_object;
4672 JumpIfNotSmi(string, &is_object);
4673 Throw(kNonObject);
4674 bind(&is_object);
4675
4676 push(value);
4677 movq(value, FieldOperand(string, HeapObject::kMapOffset));
4678 movzxbq(value, FieldOperand(value, Map::kInstanceTypeOffset));
4679
4680 andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask));
4681 cmpq(value, Immediate(encoding_mask));
4682 pop(value);
4683 ThrowIf(not_equal, kUnexpectedStringType);
4684
4685 // The index is assumed to be untagged coming in, tag it to compare with the
4686 // string length without using a temp register, it is restored at the end of
4687 // this function.
4688 Integer32ToSmi(index, index);
4689 SmiCompare(index, FieldOperand(string, String::kLengthOffset));
4690 ThrowIf(greater_equal, kIndexIsTooLarge);
4691
4692 SmiCompare(index, Smi::FromInt(0));
4693 ThrowIf(less, kIndexIsNegative);
4694
4695 // Restore the index
4696 SmiToInteger32(index, index);
4697 }
4698
4699
4638 void MacroAssembler::PrepareCallCFunction(int num_arguments) { 4700 void MacroAssembler::PrepareCallCFunction(int num_arguments) {
4639 int frame_alignment = OS::ActivationFrameAlignment(); 4701 int frame_alignment = OS::ActivationFrameAlignment();
4640 ASSERT(frame_alignment != 0); 4702 ASSERT(frame_alignment != 0);
4641 ASSERT(num_arguments >= 0); 4703 ASSERT(num_arguments >= 0);
4642 4704
4643 // Make stack end at alignment and allocate space for arguments and old rsp. 4705 // Make stack end at alignment and allocate space for arguments and old rsp.
4644 movq(kScratchRegister, rsp); 4706 movq(kScratchRegister, rsp);
4645 ASSERT(IsPowerOf2(frame_alignment)); 4707 ASSERT(IsPowerOf2(frame_alignment));
4646 int argument_slots_on_stack = 4708 int argument_slots_on_stack =
4647 ArgumentStackSlotsForCFunctionCall(num_arguments); 4709 ArgumentStackSlotsForCFunctionCall(num_arguments);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
4912 Label next, start; 4974 Label next, start;
4913 Register empty_fixed_array_value = r8; 4975 Register empty_fixed_array_value = r8;
4914 LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); 4976 LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
4915 movq(rcx, rax); 4977 movq(rcx, rax);
4916 4978
4917 // Check if the enum length field is properly initialized, indicating that 4979 // Check if the enum length field is properly initialized, indicating that
4918 // there is an enum cache. 4980 // there is an enum cache.
4919 movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 4981 movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
4920 4982
4921 EnumLength(rdx, rbx); 4983 EnumLength(rdx, rbx);
4922 Cmp(rdx, Smi::FromInt(Map::kInvalidEnumCache)); 4984 Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel));
4923 j(equal, call_runtime); 4985 j(equal, call_runtime);
4924 4986
4925 jmp(&start); 4987 jmp(&start);
4926 4988
4927 bind(&next); 4989 bind(&next);
4928 4990
4929 movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 4991 movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
4930 4992
4931 // For all objects but the receiver, check that the cache is empty. 4993 // For all objects but the receiver, check that the cache is empty.
4932 EnumLength(rdx, rbx); 4994 EnumLength(rdx, rbx);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4989 j(equal, found); 5051 j(equal, found);
4990 movq(current, FieldOperand(current, Map::kPrototypeOffset)); 5052 movq(current, FieldOperand(current, Map::kPrototypeOffset));
4991 CompareRoot(current, Heap::kNullValueRootIndex); 5053 CompareRoot(current, Heap::kNullValueRootIndex);
4992 j(not_equal, &loop_again); 5054 j(not_equal, &loop_again);
4993 } 5055 }
4994 5056
4995 5057
4996 } } // namespace v8::internal 5058 } } // namespace v8::internal
4997 5059
4998 #endif // V8_TARGET_ARCH_X64 5060 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698