| OLD | NEW |
| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 } | 71 } |
| 72 | 72 |
| 73 | 73 |
| 74 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | 74 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( |
| 75 Isolate* isolate, | 75 Isolate* isolate, |
| 76 CodeStubInterfaceDescriptor* descriptor) { | 76 CodeStubInterfaceDescriptor* descriptor) { |
| 77 static Register registers[] = { rax, rbx, rcx, rdx }; | 77 static Register registers[] = { rax, rbx, rcx, rdx }; |
| 78 descriptor->register_param_count_ = 4; | 78 descriptor->register_param_count_ = 4; |
| 79 descriptor->register_params_ = registers; | 79 descriptor->register_params_ = registers; |
| 80 descriptor->deoptimization_handler_ = | 80 descriptor->deoptimization_handler_ = |
| 81 Runtime::FunctionForId(Runtime::kCreateObjectLiteralShallow)->entry; | 81 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; |
| 82 } | 82 } |
| 83 | 83 |
| 84 | 84 |
| 85 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 85 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
| 86 Isolate* isolate, | 86 Isolate* isolate, |
| 87 CodeStubInterfaceDescriptor* descriptor) { | 87 CodeStubInterfaceDescriptor* descriptor) { |
| 88 static Register registers[] = { rbx }; | 88 static Register registers[] = { rbx }; |
| 89 descriptor->register_param_count_ = 1; | 89 descriptor->register_param_count_ = 1; |
| 90 descriptor->register_params_ = registers; | 90 descriptor->register_params_ = registers; |
| 91 descriptor->deoptimization_handler_ = NULL; | 91 descriptor->deoptimization_handler_ = NULL; |
| (...skipping 2549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2641 // The original subject is in the previous stack frame. Therefore we have to | 2641 // The original subject is in the previous stack frame. Therefore we have to |
| 2642 // use rbp, which points exactly to one pointer size below the previous rsp. | 2642 // use rbp, which points exactly to one pointer size below the previous rsp. |
| 2643 // (Because creating a new stack frame pushes the previous rbp onto the stack | 2643 // (Because creating a new stack frame pushes the previous rbp onto the stack |
| 2644 // and thereby moves up rsp by one kPointerSize.) | 2644 // and thereby moves up rsp by one kPointerSize.) |
| 2645 __ movq(arg_reg_1, r15); | 2645 __ movq(arg_reg_1, r15); |
| 2646 | 2646 |
| 2647 // Locate the code entry and call it. | 2647 // Locate the code entry and call it. |
| 2648 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 2648 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 2649 __ call(r11); | 2649 __ call(r11); |
| 2650 | 2650 |
| 2651 __ LeaveApiExitFrame(); | 2651 __ LeaveApiExitFrame(true); |
| 2652 | 2652 |
| 2653 // Check the result. | 2653 // Check the result. |
| 2654 Label success; | 2654 Label success; |
| 2655 Label exception; | 2655 Label exception; |
| 2656 __ cmpl(rax, Immediate(1)); | 2656 __ cmpl(rax, Immediate(1)); |
| 2657 // We expect exactly one result since we force the called regexp to behave | 2657 // We expect exactly one result since we force the called regexp to behave |
| 2658 // as non-global. | 2658 // as non-global. |
| 2659 __ j(equal, &success, Label::kNear); | 2659 __ j(equal, &success, Label::kNear); |
| 2660 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION)); | 2660 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION)); |
| 2661 __ j(equal, &exception); | 2661 __ j(equal, &exception); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2902 __ jmp(&loop); | 2902 __ jmp(&loop); |
| 2903 | 2903 |
| 2904 __ bind(&done); | 2904 __ bind(&done); |
| 2905 __ ret(3 * kPointerSize); | 2905 __ ret(3 * kPointerSize); |
| 2906 | 2906 |
| 2907 __ bind(&slowcase); | 2907 __ bind(&slowcase); |
| 2908 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); | 2908 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); |
| 2909 } | 2909 } |
| 2910 | 2910 |
| 2911 | 2911 |
| 2912 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | |
| 2913 Register object, | |
| 2914 Register result, | |
| 2915 Register scratch1, | |
| 2916 Register scratch2, | |
| 2917 Label* not_found) { | |
| 2918 // Use of registers. Register result is used as a temporary. | |
| 2919 Register number_string_cache = result; | |
| 2920 Register mask = scratch1; | |
| 2921 Register scratch = scratch2; | |
| 2922 | |
| 2923 // Load the number string cache. | |
| 2924 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | |
| 2925 | |
| 2926 // Make the hash mask from the length of the number string cache. It | |
| 2927 // contains two elements (number and string) for each cache entry. | |
| 2928 __ SmiToInteger32( | |
| 2929 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | |
| 2930 __ shrl(mask, Immediate(1)); | |
| 2931 __ subq(mask, Immediate(1)); // Make mask. | |
| 2932 | |
| 2933 // Calculate the entry in the number string cache. The hash value in the | |
| 2934 // number string cache for smis is just the smi value, and the hash for | |
| 2935 // doubles is the xor of the upper and lower words. See | |
| 2936 // Heap::GetNumberStringCache. | |
| 2937 Label is_smi; | |
| 2938 Label load_result_from_cache; | |
| 2939 Factory* factory = masm->isolate()->factory(); | |
| 2940 __ JumpIfSmi(object, &is_smi); | |
| 2941 __ CheckMap(object, | |
| 2942 factory->heap_number_map(), | |
| 2943 not_found, | |
| 2944 DONT_DO_SMI_CHECK); | |
| 2945 | |
| 2946 STATIC_ASSERT(8 == kDoubleSize); | |
| 2947 __ movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); | |
| 2948 __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); | |
| 2949 GenerateConvertHashCodeToIndex(masm, scratch, mask); | |
| 2950 | |
| 2951 Register index = scratch; | |
| 2952 Register probe = mask; | |
| 2953 __ movq(probe, | |
| 2954 FieldOperand(number_string_cache, | |
| 2955 index, | |
| 2956 times_1, | |
| 2957 FixedArray::kHeaderSize)); | |
| 2958 __ JumpIfSmi(probe, not_found); | |
| 2959 __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); | |
| 2960 __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset)); | |
| 2961 __ ucomisd(xmm0, xmm1); | |
| 2962 __ j(parity_even, not_found); // Bail out if NaN is involved. | |
| 2963 __ j(not_equal, not_found); // The cache did not contain this value. | |
| 2964 __ jmp(&load_result_from_cache); | |
| 2965 | |
| 2966 __ bind(&is_smi); | |
| 2967 __ SmiToInteger32(scratch, object); | |
| 2968 GenerateConvertHashCodeToIndex(masm, scratch, mask); | |
| 2969 | |
| 2970 // Check if the entry is the smi we are looking for. | |
| 2971 __ cmpq(object, | |
| 2972 FieldOperand(number_string_cache, | |
| 2973 index, | |
| 2974 times_1, | |
| 2975 FixedArray::kHeaderSize)); | |
| 2976 __ j(not_equal, not_found); | |
| 2977 | |
| 2978 // Get the result from the cache. | |
| 2979 __ bind(&load_result_from_cache); | |
| 2980 __ movq(result, | |
| 2981 FieldOperand(number_string_cache, | |
| 2982 index, | |
| 2983 times_1, | |
| 2984 FixedArray::kHeaderSize + kPointerSize)); | |
| 2985 Counters* counters = masm->isolate()->counters(); | |
| 2986 __ IncrementCounter(counters->number_to_string_native(), 1); | |
| 2987 } | |
| 2988 | |
| 2989 | |
| 2990 void NumberToStringStub::GenerateConvertHashCodeToIndex(MacroAssembler* masm, | |
| 2991 Register hash, | |
| 2992 Register mask) { | |
| 2993 __ and_(hash, mask); | |
| 2994 // Each entry in string cache consists of two pointer sized fields, | |
| 2995 // but times_twice_pointer_size (multiplication by 16) scale factor | |
| 2996 // is not supported by addrmode on x64 platform. | |
| 2997 // So we have to premultiply entry index before lookup. | |
| 2998 __ shl(hash, Immediate(kPointerSizeLog2 + 1)); | |
| 2999 } | |
| 3000 | |
| 3001 | |
| 3002 void NumberToStringStub::Generate(MacroAssembler* masm) { | 2912 void NumberToStringStub::Generate(MacroAssembler* masm) { |
| 3003 Label runtime; | 2913 Label runtime; |
| 3004 | 2914 |
| 3005 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 2915 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); |
| 3006 __ movq(rbx, args.GetArgumentOperand(0)); | 2916 __ movq(rbx, args.GetArgumentOperand(0)); |
| 3007 | 2917 |
| 3008 // Generate code to lookup number in the number string cache. | 2918 // Generate code to lookup number in the number string cache. |
| 3009 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, &runtime); | 2919 __ LookupNumberStringCache(rbx, rax, r8, r9, &runtime); |
| 3010 __ ret(1 * kPointerSize); | 2920 __ ret(1 * kPointerSize); |
| 3011 | 2921 |
| 3012 __ bind(&runtime); | 2922 __ bind(&runtime); |
| 3013 // Handle number to string in the runtime system if not found in the cache. | 2923 // Handle number to string in the runtime system if not found in the cache. |
| 3014 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); | 2924 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
| 3015 } | 2925 } |
| 3016 | 2926 |
| 3017 | 2927 |
| 3018 static int NegativeComparisonResult(Condition cc) { | 2928 static int NegativeComparisonResult(Condition cc) { |
| 3019 ASSERT(cc != equal); | 2929 ASSERT(cc != equal); |
| (...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4639 Label* slow) { | 4549 Label* slow) { |
| 4640 // First check if the argument is already a string. | 4550 // First check if the argument is already a string. |
| 4641 Label not_string, done; | 4551 Label not_string, done; |
| 4642 __ JumpIfSmi(arg, ¬_string); | 4552 __ JumpIfSmi(arg, ¬_string); |
| 4643 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1); | 4553 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1); |
| 4644 __ j(below, &done); | 4554 __ j(below, &done); |
| 4645 | 4555 |
| 4646 // Check the number to string cache. | 4556 // Check the number to string cache. |
| 4647 __ bind(¬_string); | 4557 __ bind(¬_string); |
| 4648 // Puts the cached result into scratch1. | 4558 // Puts the cached result into scratch1. |
| 4649 NumberToStringStub::GenerateLookupNumberStringCache(masm, | 4559 __ LookupNumberStringCache(arg, scratch1, scratch2, scratch3, slow); |
| 4650 arg, | |
| 4651 scratch1, | |
| 4652 scratch2, | |
| 4653 scratch3, | |
| 4654 slow); | |
| 4655 __ movq(arg, scratch1); | 4560 __ movq(arg, scratch1); |
| 4656 __ movq(Operand(rsp, stack_offset), arg); | 4561 __ movq(Operand(rsp, stack_offset), arg); |
| 4657 __ bind(&done); | 4562 __ bind(&done); |
| 4658 } | 4563 } |
| 4659 | 4564 |
| 4660 | 4565 |
| 4661 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, | 4566 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, |
| 4662 Register dest, | 4567 Register dest, |
| 4663 Register src, | 4568 Register src, |
| 4664 Register count, | 4569 Register count, |
| (...skipping 1976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6641 __ bind(&fast_elements_case); | 6546 __ bind(&fast_elements_case); |
| 6642 GenerateCase(masm, FAST_ELEMENTS); | 6547 GenerateCase(masm, FAST_ELEMENTS); |
| 6643 } | 6548 } |
| 6644 | 6549 |
| 6645 | 6550 |
| 6646 #undef __ | 6551 #undef __ |
| 6647 | 6552 |
| 6648 } } // namespace v8::internal | 6553 } } // namespace v8::internal |
| 6649 | 6554 |
| 6650 #endif // V8_TARGET_ARCH_X64 | 6555 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |