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

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

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 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/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 InvokeFlag flag, 812 InvokeFlag flag,
813 const CallWrapper& call_wrapper) { 813 const CallWrapper& call_wrapper) {
814 // Calls are not allowed in some stubs. 814 // Calls are not allowed in some stubs.
815 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); 815 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
816 816
817 // Rely on the assertion to check that the number of provided 817 // Rely on the assertion to check that the number of provided
818 // arguments match the expected number of arguments. Fake a 818 // arguments match the expected number of arguments. Fake a
819 // parameter count to avoid emitting code to do the check. 819 // parameter count to avoid emitting code to do the check.
820 ParameterCount expected(0); 820 ParameterCount expected(0);
821 GetBuiltinEntry(rdx, id); 821 GetBuiltinEntry(rdx, id);
822 InvokeCode(rdx, expected, expected, flag, call_wrapper); 822 InvokeCode(rdx, expected, expected, flag, call_wrapper, CALL_AS_METHOD);
823 } 823 }
824 824
825 825
826 void MacroAssembler::GetBuiltinFunction(Register target, 826 void MacroAssembler::GetBuiltinFunction(Register target,
827 Builtins::JavaScript id) { 827 Builtins::JavaScript id) {
828 // Load the builtins object into target register. 828 // Load the builtins object into target register.
829 movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); 829 movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
830 movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); 830 movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
831 movq(target, FieldOperand(target, 831 movq(target, FieldOperand(target,
832 JSBuiltinsObject::OffsetOfFunctionWithId(id))); 832 JSBuiltinsObject::OffsetOfFunctionWithId(id)));
(...skipping 1788 matching lines...) Expand 10 before | Expand all | Expand 10 after
2621 CmpInstanceType(map, type); 2621 CmpInstanceType(map, type);
2622 } 2622 }
2623 2623
2624 2624
2625 void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 2625 void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
2626 cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 2626 cmpb(FieldOperand(map, Map::kInstanceTypeOffset),
2627 Immediate(static_cast<int8_t>(type))); 2627 Immediate(static_cast<int8_t>(type)));
2628 } 2628 }
2629 2629
2630 2630
2631 void MacroAssembler::CheckFastElements(Register map,
2632 Label* fail,
2633 Label::Distance distance) {
2634 STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0);
2635 cmpb(FieldOperand(map, Map::kBitField2Offset),
2636 Immediate(Map::kMaximumBitField2FastElementValue));
2637 j(above, fail, distance);
2638 }
2639
2640
2631 void MacroAssembler::CheckMap(Register obj, 2641 void MacroAssembler::CheckMap(Register obj,
2632 Handle<Map> map, 2642 Handle<Map> map,
2633 Label* fail, 2643 Label* fail,
2634 SmiCheckType smi_check_type) { 2644 SmiCheckType smi_check_type) {
2635 if (smi_check_type == DO_SMI_CHECK) { 2645 if (smi_check_type == DO_SMI_CHECK) {
2636 JumpIfSmi(obj, fail); 2646 JumpIfSmi(obj, fail);
2637 } 2647 }
2638 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 2648 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
2639 j(not_equal, fail); 2649 j(not_equal, fail);
2640 } 2650 }
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2951 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2942 2952
2943 ParameterCount expected(rbx); 2953 ParameterCount expected(rbx);
2944 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); 2954 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind);
2945 } 2955 }
2946 2956
2947 2957
2948 void MacroAssembler::InvokeFunction(JSFunction* function, 2958 void MacroAssembler::InvokeFunction(JSFunction* function,
2949 const ParameterCount& actual, 2959 const ParameterCount& actual,
2950 InvokeFlag flag, 2960 InvokeFlag flag,
2951 const CallWrapper& call_wrapper) { 2961 const CallWrapper& call_wrapper,
2962 CallKind call_kind) {
2952 ASSERT(function->is_compiled()); 2963 ASSERT(function->is_compiled());
2953 // Get the function and setup the context. 2964 // Get the function and setup the context.
2954 Move(rdi, Handle<JSFunction>(function)); 2965 Move(rdi, Handle<JSFunction>(function));
2955 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2966 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2956 2967
2957 if (V8::UseCrankshaft()) { 2968 if (V8::UseCrankshaft()) {
2958 // Since Crankshaft can recompile a function, we need to load 2969 // Since Crankshaft can recompile a function, we need to load
2959 // the Code object every time we call the function. 2970 // the Code object every time we call the function.
2960 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2971 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2961 ParameterCount expected(function->shared()->formal_parameter_count()); 2972 ParameterCount expected(function->shared()->formal_parameter_count());
2962 InvokeCode(rdx, expected, actual, flag, call_wrapper); 2973 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind);
2963 } else { 2974 } else {
2964 // Invoke the cached code. 2975 // Invoke the cached code.
2965 Handle<Code> code(function->code()); 2976 Handle<Code> code(function->code());
2966 ParameterCount expected(function->shared()->formal_parameter_count()); 2977 ParameterCount expected(function->shared()->formal_parameter_count());
2967 InvokeCode(code, 2978 InvokeCode(code,
2968 expected, 2979 expected,
2969 actual, 2980 actual,
2970 RelocInfo::CODE_TARGET, 2981 RelocInfo::CODE_TARGET,
2971 flag, 2982 flag,
2972 call_wrapper); 2983 call_wrapper,
2984 call_kind);
2973 } 2985 }
2974 } 2986 }
2975 2987
2976 2988
2977 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 2989 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
2978 const ParameterCount& actual, 2990 const ParameterCount& actual,
2979 Handle<Code> code_constant, 2991 Handle<Code> code_constant,
2980 Register code_register, 2992 Register code_register,
2981 Label* done, 2993 Label* done,
2982 InvokeFlag flag, 2994 InvokeFlag flag,
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3255 int token_offset = 3267 int token_offset =
3256 Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize; 3268 Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize;
3257 movq(scratch, FieldOperand(scratch, token_offset)); 3269 movq(scratch, FieldOperand(scratch, token_offset));
3258 cmpq(scratch, FieldOperand(kScratchRegister, token_offset)); 3270 cmpq(scratch, FieldOperand(kScratchRegister, token_offset));
3259 j(not_equal, miss); 3271 j(not_equal, miss);
3260 3272
3261 bind(&same_contexts); 3273 bind(&same_contexts);
3262 } 3274 }
3263 3275
3264 3276
3277 void MacroAssembler::LoadFromNumberDictionary(Label* miss,
3278 Register elements,
3279 Register key,
3280 Register r0,
3281 Register r1,
3282 Register r2,
3283 Register result) {
3284 // Register use:
3285 //
3286 // elements - holds the slow-case elements of the receiver on entry.
3287 // Unchanged unless 'result' is the same register.
3288 //
3289 // key - holds the smi key on entry.
3290 // Unchanged unless 'result' is the same register.
3291 //
3292 // Scratch registers:
3293 //
3294 // r0 - holds the untagged key on entry and holds the hash once computed.
3295 //
3296 // r1 - used to hold the capacity mask of the dictionary
3297 //
3298 // r2 - used for the index into the dictionary.
3299 //
3300 // result - holds the result on exit if the load succeeded.
3301 // Allowed to be the same as 'key' or 'result'.
3302 // Unchanged on bailout so 'key' or 'result' can be used
3303 // in further computation.
3304
3305 Label done;
3306
3307 // Compute the hash code from the untagged key. This must be kept in sync
3308 // with ComputeIntegerHash in utils.h.
3309 //
3310 // hash = ~hash + (hash << 15);
3311 movl(r1, r0);
3312 notl(r0);
3313 shll(r1, Immediate(15));
3314 addl(r0, r1);
3315 // hash = hash ^ (hash >> 12);
3316 movl(r1, r0);
3317 shrl(r1, Immediate(12));
3318 xorl(r0, r1);
3319 // hash = hash + (hash << 2);
3320 leal(r0, Operand(r0, r0, times_4, 0));
3321 // hash = hash ^ (hash >> 4);
3322 movl(r1, r0);
3323 shrl(r1, Immediate(4));
3324 xorl(r0, r1);
3325 // hash = hash * 2057;
3326 imull(r0, r0, Immediate(2057));
3327 // hash = hash ^ (hash >> 16);
3328 movl(r1, r0);
3329 shrl(r1, Immediate(16));
3330 xorl(r0, r1);
3331
3332 // Compute capacity mask.
3333 SmiToInteger32(r1,
3334 FieldOperand(elements, NumberDictionary::kCapacityOffset));
3335 decl(r1);
3336
3337 // Generate an unrolled loop that performs a few probes before giving up.
3338 const int kProbes = 4;
3339 for (int i = 0; i < kProbes; i++) {
3340 // Use r2 for index calculations and keep the hash intact in r0.
3341 movq(r2, r0);
3342 // Compute the masked index: (hash + i + i * i) & mask.
3343 if (i > 0) {
3344 addl(r2, Immediate(NumberDictionary::GetProbeOffset(i)));
3345 }
3346 and_(r2, r1);
3347
3348 // Scale the index by multiplying by the entry size.
3349 ASSERT(NumberDictionary::kEntrySize == 3);
3350 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
3351
3352 // Check if the key matches.
3353 cmpq(key, FieldOperand(elements,
3354 r2,
3355 times_pointer_size,
3356 NumberDictionary::kElementsStartOffset));
3357 if (i != (kProbes - 1)) {
3358 j(equal, &done);
3359 } else {
3360 j(not_equal, miss);
3361 }
3362 }
3363
3364 bind(&done);
3365 // Check that the value is a normal propety.
3366 const int kDetailsOffset =
3367 NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
3368 ASSERT_EQ(NORMAL, 0);
3369 Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
3370 Smi::FromInt(PropertyDetails::TypeField::mask()));
3371 j(not_zero, miss);
3372
3373 // Get the value at the masked, scaled index.
3374 const int kValueOffset =
3375 NumberDictionary::kElementsStartOffset + kPointerSize;
3376 movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
3377 }
3378
3379
3265 void MacroAssembler::LoadAllocationTopHelper(Register result, 3380 void MacroAssembler::LoadAllocationTopHelper(Register result,
3266 Register scratch, 3381 Register scratch,
3267 AllocationFlags flags) { 3382 AllocationFlags flags) {
3268 ExternalReference new_space_allocation_top = 3383 ExternalReference new_space_allocation_top =
3269 ExternalReference::new_space_allocation_top_address(isolate()); 3384 ExternalReference::new_space_allocation_top_address(isolate());
3270 3385
3271 // Just return if allocation top is already known. 3386 // Just return if allocation top is already known.
3272 if ((flags & RESULT_CONTAINS_TOP) != 0) { 3387 if ((flags & RESULT_CONTAINS_TOP) != 0) {
3273 // No use of scratch if allocation top is provided. 3388 // No use of scratch if allocation top is provided.
3274 ASSERT(!scratch.is_valid()); 3389 ASSERT(!scratch.is_valid());
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
3668 j(not_equal, &short_loop); 3783 j(not_equal, &short_loop);
3669 3784
3670 bind(&done); 3785 bind(&done);
3671 } 3786 }
3672 } 3787 }
3673 3788
3674 3789
3675 void MacroAssembler::LoadContext(Register dst, int context_chain_length) { 3790 void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
3676 if (context_chain_length > 0) { 3791 if (context_chain_length > 0) {
3677 // Move up the chain of contexts to the context containing the slot. 3792 // Move up the chain of contexts to the context containing the slot.
3678 movq(dst, Operand(rsi, Context::SlotOffset(Context::CLOSURE_INDEX))); 3793 movq(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3679 // Load the function context (which is the incoming, outer context).
3680 movq(dst, FieldOperand(dst, JSFunction::kContextOffset));
3681 for (int i = 1; i < context_chain_length; i++) { 3794 for (int i = 1; i < context_chain_length; i++) {
3682 movq(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX))); 3795 movq(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3683 movq(dst, FieldOperand(dst, JSFunction::kContextOffset));
3684 } 3796 }
3685 // The context may be an intermediate context, not a function context.
3686 movq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
3687 } else { 3797 } else {
3688 // Slot is in the current function context. Move it into the 3798 // Slot is in the current function context. Move it into the
3689 // destination register in case we store into it (the write barrier 3799 // destination register in case we store into it (the write barrier
3690 // cannot be allowed to destroy the context in rsi). 3800 // cannot be allowed to destroy the context in rsi).
3691 movq(dst, rsi); 3801 movq(dst, rsi);
3692 } 3802 }
3693 3803
3694 // We should not have found a 'with' context by walking the context chain 3804 // We should not have found a with context by walking the context
3695 // (i.e., the static scope chain and runtime context chain do not agree). 3805 // chain (i.e., the static scope chain and runtime context chain do
3696 // A variable occurring in such a scope should have slot type LOOKUP and 3806 // not agree). A variable occurring in such a scope should have
3697 // not CONTEXT. 3807 // slot type LOOKUP and not CONTEXT.
3698 if (emit_debug_code()) { 3808 if (emit_debug_code()) {
3699 cmpq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX))); 3809 CompareRoot(FieldOperand(dst, HeapObject::kMapOffset),
3700 Check(equal, "Yo dawg, I heard you liked function contexts " 3810 Heap::kWithContextMapRootIndex);
3701 "so I put function contexts in all your contexts"); 3811 Check(not_equal, "Variable resolved to with context.");
3702 } 3812 }
3703 } 3813 }
3704 3814
3705 #ifdef _WIN64 3815 #ifdef _WIN64
3706 static const int kRegisterPassedArguments = 4; 3816 static const int kRegisterPassedArguments = 4;
3707 #else 3817 #else
3708 static const int kRegisterPassedArguments = 6; 3818 static const int kRegisterPassedArguments = 6;
3709 #endif 3819 #endif
3710 3820
3711 void MacroAssembler::LoadGlobalFunction(int index, Register function) { 3821 void MacroAssembler::LoadGlobalFunction(int index, Register function) {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
3910 movq(rcx, addr_reg); 4020 movq(rcx, addr_reg);
3911 shrl(rcx, Immediate(kPointerSizeLog2)); 4021 shrl(rcx, Immediate(kPointerSizeLog2));
3912 and_(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 4022 and_(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1));
3913 movl(mask_reg, Immediate(1)); 4023 movl(mask_reg, Immediate(1));
3914 shl_cl(mask_reg); 4024 shl_cl(mask_reg);
3915 } 4025 }
3916 4026
3917 } } // namespace v8::internal 4027 } } // namespace v8::internal
3918 4028
3919 #endif // V8_TARGET_ARCH_X64 4029 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698