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

Side by Side Diff: src/x64/builtins-x64.cc

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 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/assembler-x64-inl.h ('k') | src/x64/codegen-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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kConstructStubOffset)); 91 __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kConstructStubOffset));
92 __ lea(rbx, FieldOperand(rbx, Code::kHeaderSize)); 92 __ lea(rbx, FieldOperand(rbx, Code::kHeaderSize));
93 __ jmp(rbx); 93 __ jmp(rbx);
94 94
95 // rdi: called object 95 // rdi: called object
96 // rax: number of arguments 96 // rax: number of arguments
97 __ bind(&non_function_call); 97 __ bind(&non_function_call);
98 // Set expected number of arguments to zero (not changing rax). 98 // Set expected number of arguments to zero (not changing rax).
99 __ movq(rbx, Immediate(0)); 99 __ movq(rbx, Immediate(0));
100 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 100 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
101 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), 101 __ Jump(Handle<Code>(Isolate::Current()->builtins()->builtin(
102 RelocInfo::CODE_TARGET); 102 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
103 } 103 }
104 104
105 105
106 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 106 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
107 bool is_api_function, 107 bool is_api_function,
108 bool count_constructions) { 108 bool count_constructions) {
109 // Should never count constructions for api objects. 109 // Should never count constructions for api objects.
110 ASSERT(!is_api_function || !count_constructions); 110 ASSERT(!is_api_function || !count_constructions);
111 111
112 // Enter a construct frame. 112 // Enter a construct frame.
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 __ jmp(&entry); 332 __ jmp(&entry);
333 __ bind(&loop); 333 __ bind(&loop);
334 __ push(Operand(rbx, rcx, times_pointer_size, 0)); 334 __ push(Operand(rbx, rcx, times_pointer_size, 0));
335 __ bind(&entry); 335 __ bind(&entry);
336 __ decq(rcx); 336 __ decq(rcx);
337 __ j(greater_equal, &loop); 337 __ j(greater_equal, &loop);
338 338
339 // Call the function. 339 // Call the function.
340 if (is_api_function) { 340 if (is_api_function) {
341 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 341 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
342 Handle<Code> code = Handle<Code>( 342 Handle<Code> code = Handle<Code>(Isolate::Current()->builtins()->builtin(
343 Builtins::builtin(Builtins::HandleApiCallConstruct)); 343 Builtins::HandleApiCallConstruct));
344 ParameterCount expected(0); 344 ParameterCount expected(0);
345 __ InvokeCode(code, expected, expected, 345 __ InvokeCode(code, expected, expected,
346 RelocInfo::CODE_TARGET, CALL_FUNCTION); 346 RelocInfo::CODE_TARGET, CALL_FUNCTION);
347 } else { 347 } else {
348 ParameterCount actual(rax); 348 ParameterCount actual(rax);
349 __ InvokeFunction(rdi, actual, CALL_FUNCTION); 349 __ InvokeFunction(rdi, actual, CALL_FUNCTION);
350 } 350 }
351 351
352 // Restore context from the frame. 352 // Restore context from the frame.
353 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 353 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
(...skipping 18 matching lines...) Expand all
372 // Restore the arguments count and leave the construct frame. 372 // Restore the arguments count and leave the construct frame.
373 __ bind(&exit); 373 __ bind(&exit);
374 __ movq(rbx, Operand(rsp, kPointerSize)); // get arguments count 374 __ movq(rbx, Operand(rsp, kPointerSize)); // get arguments count
375 __ LeaveConstructFrame(); 375 __ LeaveConstructFrame();
376 376
377 // Remove caller arguments from the stack and return. 377 // Remove caller arguments from the stack and return.
378 __ pop(rcx); 378 __ pop(rcx);
379 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); 379 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
380 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); 380 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
381 __ push(rcx); 381 __ push(rcx);
382 __ IncrementCounter(&Counters::constructed_objects, 1); 382 __ IncrementCounter(COUNTERS->constructed_objects(), 1);
383 __ ret(0); 383 __ ret(0);
384 } 384 }
385 385
386 386
387 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { 387 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
388 Generate_JSConstructStubHelper(masm, false, true); 388 Generate_JSConstructStubHelper(masm, false, true);
389 } 389 }
390 390
391 391
392 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 392 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 __ movq(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0)); 485 __ movq(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0));
486 __ push(Operand(kScratchRegister, 0)); // dereference handle 486 __ push(Operand(kScratchRegister, 0)); // dereference handle
487 __ addq(rcx, Immediate(1)); 487 __ addq(rcx, Immediate(1));
488 __ bind(&entry); 488 __ bind(&entry);
489 __ cmpq(rcx, rax); 489 __ cmpq(rcx, rax);
490 __ j(not_equal, &loop); 490 __ j(not_equal, &loop);
491 491
492 // Invoke the code. 492 // Invoke the code.
493 if (is_construct) { 493 if (is_construct) {
494 // Expects rdi to hold function pointer. 494 // Expects rdi to hold function pointer.
495 __ Call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), 495 __ Call(Handle<Code>(Isolate::Current()->builtins()->builtin(
496 RelocInfo::CODE_TARGET); 496 Builtins::JSConstructCall)), RelocInfo::CODE_TARGET);
497 } else { 497 } else {
498 ParameterCount actual(rax); 498 ParameterCount actual(rax);
499 // Function must be in rdi. 499 // Function must be in rdi.
500 __ InvokeFunction(rdi, actual, CALL_FUNCTION); 500 __ InvokeFunction(rdi, actual, CALL_FUNCTION);
501 } 501 }
502 502
503 // Exit the JS frame. Notice that this also removes the empty 503 // Exit the JS frame. Notice that this also removes the empty
504 // context and the function left on the stack by the code 504 // context and the function left on the stack by the code
505 // invocation. 505 // invocation.
506 __ LeaveInternalFrame(); 506 __ LeaveInternalFrame();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 // rsp[n]: Argument 1 623 // rsp[n]: Argument 1
624 // rsp[n+1]: Receiver (function to call) 624 // rsp[n+1]: Receiver (function to call)
625 // 625 //
626 // rax contains the number of arguments, n, not counting the receiver. 626 // rax contains the number of arguments, n, not counting the receiver.
627 // 627 //
628 // 1. Make sure we have at least one argument. 628 // 1. Make sure we have at least one argument.
629 { Label done; 629 { Label done;
630 __ testq(rax, rax); 630 __ testq(rax, rax);
631 __ j(not_zero, &done); 631 __ j(not_zero, &done);
632 __ pop(rbx); 632 __ pop(rbx);
633 __ Push(Factory::undefined_value()); 633 __ Push(FACTORY->undefined_value());
634 __ push(rbx); 634 __ push(rbx);
635 __ incq(rax); 635 __ incq(rax);
636 __ bind(&done); 636 __ bind(&done);
637 } 637 }
638 638
639 // 2. Get the function to call (passed as receiver) from the stack, check 639 // 2. Get the function to call (passed as receiver) from the stack, check
640 // if it is a function. 640 // if it is a function.
641 Label non_function; 641 Label non_function;
642 // The function to call is at position n+1 on the stack. 642 // The function to call is at position n+1 on the stack.
643 __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); 643 __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 __ pop(rbx); // Discard copy of return address. 726 __ pop(rbx); // Discard copy of return address.
727 __ decq(rax); // One fewer argument (first argument is new receiver). 727 __ decq(rax); // One fewer argument (first argument is new receiver).
728 } 728 }
729 729
730 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. 730 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin.
731 { Label function; 731 { Label function;
732 __ testq(rdi, rdi); 732 __ testq(rdi, rdi);
733 __ j(not_zero, &function); 733 __ j(not_zero, &function);
734 __ Set(rbx, 0); 734 __ Set(rbx, 0);
735 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); 735 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
736 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), 736 __ Jump(Handle<Code>(Isolate::Current()->builtins()->builtin(
737 RelocInfo::CODE_TARGET); 737 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
738 __ bind(&function); 738 __ bind(&function);
739 } 739 }
740 740
741 // 5b. Get the code to call from the function and check that the number of 741 // 5b. Get the code to call from the function and check that the number of
742 // expected arguments matches what we're providing. If so, jump 742 // expected arguments matches what we're providing. If so, jump
743 // (tail-call) to the code in register edx without checking arguments. 743 // (tail-call) to the code in register edx without checking arguments.
744 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 744 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
745 __ movsxlq(rbx, 745 __ movsxlq(rbx,
746 FieldOperand(rdx, 746 FieldOperand(rdx,
747 SharedFunctionInfo::kFormalParameterCountOffset)); 747 SharedFunctionInfo::kFormalParameterCountOffset));
748 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 748 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
749 __ cmpq(rax, rbx); 749 __ cmpq(rax, rbx);
750 __ j(not_equal, 750 __ j(not_equal,
751 Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), 751 Handle<Code>(Isolate::Current()->builtins()->builtin(
752 RelocInfo::CODE_TARGET); 752 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
753 753
754 ParameterCount expected(0); 754 ParameterCount expected(0);
755 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION); 755 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION);
756 } 756 }
757 757
758 758
759 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 759 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
760 // Stack at entry: 760 // Stack at entry:
761 // rsp: return address 761 // rsp: return address
762 // rsp+8: arguments 762 // rsp+8: arguments
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 __ push(rbx); 856 __ push(rbx);
857 857
858 // Copy all arguments from the array to the stack. 858 // Copy all arguments from the array to the stack.
859 Label entry, loop; 859 Label entry, loop;
860 __ movq(rax, Operand(rbp, kIndexOffset)); 860 __ movq(rax, Operand(rbp, kIndexOffset));
861 __ jmp(&entry); 861 __ jmp(&entry);
862 __ bind(&loop); 862 __ bind(&loop);
863 __ movq(rdx, Operand(rbp, kArgumentsOffset)); // load arguments 863 __ movq(rdx, Operand(rbp, kArgumentsOffset)); // load arguments
864 864
865 // Use inline caching to speed up access to arguments. 865 // Use inline caching to speed up access to arguments.
866 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 866 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
867 Builtins::KeyedLoadIC_Initialize));
867 __ Call(ic, RelocInfo::CODE_TARGET); 868 __ Call(ic, RelocInfo::CODE_TARGET);
868 // It is important that we do not have a test instruction after the 869 // It is important that we do not have a test instruction after the
869 // call. A test instruction after the call is used to indicate that 870 // call. A test instruction after the call is used to indicate that
870 // we have generated an inline version of the keyed load. In this 871 // we have generated an inline version of the keyed load. In this
871 // case, we know that we are not generating a test instruction next. 872 // case, we know that we are not generating a test instruction next.
872 873
873 // Push the nth argument. 874 // Push the nth argument.
874 __ push(rax); 875 __ push(rax);
875 876
876 // Update the index on the stack and in register rax. 877 // Update the index on the stack and in register rax.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 gc_required, 929 gc_required,
929 TAG_OBJECT); 930 TAG_OBJECT);
930 931
931 // Allocated the JSArray. Now initialize the fields except for the elements 932 // Allocated the JSArray. Now initialize the fields except for the elements
932 // array. 933 // array.
933 // result: JSObject 934 // result: JSObject
934 // scratch1: initial map 935 // scratch1: initial map
935 // scratch2: start of next object 936 // scratch2: start of next object
936 __ movq(FieldOperand(result, JSObject::kMapOffset), scratch1); 937 __ movq(FieldOperand(result, JSObject::kMapOffset), scratch1);
937 __ Move(FieldOperand(result, JSArray::kPropertiesOffset), 938 __ Move(FieldOperand(result, JSArray::kPropertiesOffset),
938 Factory::empty_fixed_array()); 939 FACTORY->empty_fixed_array());
939 // Field JSArray::kElementsOffset is initialized later. 940 // Field JSArray::kElementsOffset is initialized later.
940 __ Move(FieldOperand(result, JSArray::kLengthOffset), Smi::FromInt(0)); 941 __ Move(FieldOperand(result, JSArray::kLengthOffset), Smi::FromInt(0));
941 942
942 // If no storage is requested for the elements array just set the empty 943 // If no storage is requested for the elements array just set the empty
943 // fixed array. 944 // fixed array.
944 if (initial_capacity == 0) { 945 if (initial_capacity == 0) {
945 __ Move(FieldOperand(result, JSArray::kElementsOffset), 946 __ Move(FieldOperand(result, JSArray::kElementsOffset),
946 Factory::empty_fixed_array()); 947 FACTORY->empty_fixed_array());
947 return; 948 return;
948 } 949 }
949 950
950 // Calculate the location of the elements array and set elements array member 951 // Calculate the location of the elements array and set elements array member
951 // of the JSArray. 952 // of the JSArray.
952 // result: JSObject 953 // result: JSObject
953 // scratch2: start of next object 954 // scratch2: start of next object
954 __ lea(scratch1, Operand(result, JSArray::kSize)); 955 __ lea(scratch1, Operand(result, JSArray::kSize));
955 __ movq(FieldOperand(result, JSArray::kElementsOffset), scratch1); 956 __ movq(FieldOperand(result, JSArray::kElementsOffset), scratch1);
956 957
957 // Initialize the FixedArray and fill it with holes. FixedArray length is 958 // Initialize the FixedArray and fill it with holes. FixedArray length is
958 // stored as a smi. 959 // stored as a smi.
959 // result: JSObject 960 // result: JSObject
960 // scratch1: elements array 961 // scratch1: elements array
961 // scratch2: start of next object 962 // scratch2: start of next object
962 __ Move(FieldOperand(scratch1, HeapObject::kMapOffset), 963 __ Move(FieldOperand(scratch1, HeapObject::kMapOffset),
963 Factory::fixed_array_map()); 964 FACTORY->fixed_array_map());
964 __ Move(FieldOperand(scratch1, FixedArray::kLengthOffset), 965 __ Move(FieldOperand(scratch1, FixedArray::kLengthOffset),
965 Smi::FromInt(initial_capacity)); 966 Smi::FromInt(initial_capacity));
966 967
967 // Fill the FixedArray with the hole value. Inline the code if short. 968 // Fill the FixedArray with the hole value. Inline the code if short.
968 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. 969 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed.
969 static const int kLoopUnfoldLimit = 4; 970 static const int kLoopUnfoldLimit = 4;
970 ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit); 971 ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit);
971 __ Move(scratch3, Factory::the_hole_value()); 972 __ Move(scratch3, FACTORY->the_hole_value());
972 if (initial_capacity <= kLoopUnfoldLimit) { 973 if (initial_capacity <= kLoopUnfoldLimit) {
973 // Use a scratch register here to have only one reloc info when unfolding 974 // Use a scratch register here to have only one reloc info when unfolding
974 // the loop. 975 // the loop.
975 for (int i = 0; i < initial_capacity; i++) { 976 for (int i = 0; i < initial_capacity; i++) {
976 __ movq(FieldOperand(scratch1, 977 __ movq(FieldOperand(scratch1,
977 FixedArray::kHeaderSize + i * kPointerSize), 978 FixedArray::kHeaderSize + i * kPointerSize),
978 scratch3); 979 scratch3);
979 } 980 }
980 } else { 981 } else {
981 Label loop, entry; 982 Label loop, entry;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 TAG_OBJECT); 1046 TAG_OBJECT);
1046 1047
1047 // Allocated the JSArray. Now initialize the fields except for the elements 1048 // Allocated the JSArray. Now initialize the fields except for the elements
1048 // array. 1049 // array.
1049 // result: JSObject 1050 // result: JSObject
1050 // elements_array: initial map 1051 // elements_array: initial map
1051 // elements_array_end: start of next object 1052 // elements_array_end: start of next object
1052 // array_size: size of array (smi) 1053 // array_size: size of array (smi)
1053 __ bind(&allocated); 1054 __ bind(&allocated);
1054 __ movq(FieldOperand(result, JSObject::kMapOffset), elements_array); 1055 __ movq(FieldOperand(result, JSObject::kMapOffset), elements_array);
1055 __ Move(elements_array, Factory::empty_fixed_array()); 1056 __ Move(elements_array, FACTORY->empty_fixed_array());
1056 __ movq(FieldOperand(result, JSArray::kPropertiesOffset), elements_array); 1057 __ movq(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
1057 // Field JSArray::kElementsOffset is initialized later. 1058 // Field JSArray::kElementsOffset is initialized later.
1058 __ movq(FieldOperand(result, JSArray::kLengthOffset), array_size); 1059 __ movq(FieldOperand(result, JSArray::kLengthOffset), array_size);
1059 1060
1060 // Calculate the location of the elements array and set elements array member 1061 // Calculate the location of the elements array and set elements array member
1061 // of the JSArray. 1062 // of the JSArray.
1062 // result: JSObject 1063 // result: JSObject
1063 // elements_array_end: start of next object 1064 // elements_array_end: start of next object
1064 // array_size: size of array (smi) 1065 // array_size: size of array (smi)
1065 __ lea(elements_array, Operand(result, JSArray::kSize)); 1066 __ lea(elements_array, Operand(result, JSArray::kSize));
1066 __ movq(FieldOperand(result, JSArray::kElementsOffset), elements_array); 1067 __ movq(FieldOperand(result, JSArray::kElementsOffset), elements_array);
1067 1068
1068 // Initialize the fixed array. FixedArray length is stored as a smi. 1069 // Initialize the fixed array. FixedArray length is stored as a smi.
1069 // result: JSObject 1070 // result: JSObject
1070 // elements_array: elements array 1071 // elements_array: elements array
1071 // elements_array_end: start of next object 1072 // elements_array_end: start of next object
1072 // array_size: size of array (smi) 1073 // array_size: size of array (smi)
1073 __ Move(FieldOperand(elements_array, JSObject::kMapOffset), 1074 __ Move(FieldOperand(elements_array, JSObject::kMapOffset),
1074 Factory::fixed_array_map()); 1075 FACTORY->fixed_array_map());
1075 Label not_empty_2, fill_array; 1076 Label not_empty_2, fill_array;
1076 __ SmiTest(array_size); 1077 __ SmiTest(array_size);
1077 __ j(not_zero, &not_empty_2); 1078 __ j(not_zero, &not_empty_2);
1078 // Length of the FixedArray is the number of pre-allocated elements even 1079 // Length of the FixedArray is the number of pre-allocated elements even
1079 // though the actual JSArray has length 0. 1080 // though the actual JSArray has length 0.
1080 __ Move(FieldOperand(elements_array, FixedArray::kLengthOffset), 1081 __ Move(FieldOperand(elements_array, FixedArray::kLengthOffset),
1081 Smi::FromInt(kPreallocatedArrayElements)); 1082 Smi::FromInt(kPreallocatedArrayElements));
1082 __ jmp(&fill_array); 1083 __ jmp(&fill_array);
1083 __ bind(&not_empty_2); 1084 __ bind(&not_empty_2);
1084 // For non-empty JSArrays the length of the FixedArray and the JSArray is the 1085 // For non-empty JSArrays the length of the FixedArray and the JSArray is the
1085 // same. 1086 // same.
1086 __ movq(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size); 1087 __ movq(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size);
1087 1088
1088 // Fill the allocated FixedArray with the hole value if requested. 1089 // Fill the allocated FixedArray with the hole value if requested.
1089 // result: JSObject 1090 // result: JSObject
1090 // elements_array: elements array 1091 // elements_array: elements array
1091 // elements_array_end: start of next object 1092 // elements_array_end: start of next object
1092 __ bind(&fill_array); 1093 __ bind(&fill_array);
1093 if (fill_with_hole) { 1094 if (fill_with_hole) {
1094 Label loop, entry; 1095 Label loop, entry;
1095 __ Move(scratch, Factory::the_hole_value()); 1096 __ Move(scratch, FACTORY->the_hole_value());
1096 __ lea(elements_array, Operand(elements_array, 1097 __ lea(elements_array, Operand(elements_array,
1097 FixedArray::kHeaderSize - kHeapObjectTag)); 1098 FixedArray::kHeaderSize - kHeapObjectTag));
1098 __ jmp(&entry); 1099 __ jmp(&entry);
1099 __ bind(&loop); 1100 __ bind(&loop);
1100 __ movq(Operand(elements_array, 0), scratch); 1101 __ movq(Operand(elements_array, 0), scratch);
1101 __ addq(elements_array, Immediate(kPointerSize)); 1102 __ addq(elements_array, Immediate(kPointerSize));
1102 __ bind(&entry); 1103 __ bind(&entry);
1103 __ cmpq(elements_array, elements_array_end); 1104 __ cmpq(elements_array, elements_array_end);
1104 __ j(below, &loop); 1105 __ j(below, &loop);
1105 } 1106 }
(...skipping 24 matching lines...) Expand all
1130 1131
1131 // Handle construction of an empty array. 1132 // Handle construction of an empty array.
1132 AllocateEmptyJSArray(masm, 1133 AllocateEmptyJSArray(masm,
1133 rdi, 1134 rdi,
1134 rbx, 1135 rbx,
1135 rcx, 1136 rcx,
1136 rdx, 1137 rdx,
1137 r8, 1138 r8,
1138 kPreallocatedArrayElements, 1139 kPreallocatedArrayElements,
1139 call_generic_code); 1140 call_generic_code);
1140 __ IncrementCounter(&Counters::array_function_native, 1); 1141 __ IncrementCounter(COUNTERS->array_function_native(), 1);
1141 __ movq(rax, rbx); 1142 __ movq(rax, rbx);
1142 __ ret(kPointerSize); 1143 __ ret(kPointerSize);
1143 1144
1144 // Check for one argument. Bail out if argument is not smi or if it is 1145 // Check for one argument. Bail out if argument is not smi or if it is
1145 // negative. 1146 // negative.
1146 __ bind(&argc_one_or_more); 1147 __ bind(&argc_one_or_more);
1147 __ cmpq(rax, Immediate(1)); 1148 __ cmpq(rax, Immediate(1));
1148 __ j(not_equal, &argc_two_or_more); 1149 __ j(not_equal, &argc_two_or_more);
1149 __ movq(rdx, Operand(rsp, kPointerSize)); // Get the argument from the stack. 1150 __ movq(rdx, Operand(rsp, kPointerSize)); // Get the argument from the stack.
1150 __ JumpUnlessNonNegativeSmi(rdx, call_generic_code); 1151 __ JumpUnlessNonNegativeSmi(rdx, call_generic_code);
(...skipping 10 matching lines...) Expand all
1161 // esp[8]: argument 1162 // esp[8]: argument
1162 AllocateJSArray(masm, 1163 AllocateJSArray(masm,
1163 rdi, 1164 rdi,
1164 rdx, 1165 rdx,
1165 rbx, 1166 rbx,
1166 rcx, 1167 rcx,
1167 r8, 1168 r8,
1168 r9, 1169 r9,
1169 true, 1170 true,
1170 call_generic_code); 1171 call_generic_code);
1171 __ IncrementCounter(&Counters::array_function_native, 1); 1172 __ IncrementCounter(COUNTERS->array_function_native(), 1);
1172 __ movq(rax, rbx); 1173 __ movq(rax, rbx);
1173 __ ret(2 * kPointerSize); 1174 __ ret(2 * kPointerSize);
1174 1175
1175 // Handle construction of an array from a list of arguments. 1176 // Handle construction of an array from a list of arguments.
1176 __ bind(&argc_two_or_more); 1177 __ bind(&argc_two_or_more);
1177 __ movq(rdx, rax); 1178 __ movq(rdx, rax);
1178 __ Integer32ToSmi(rdx, rdx); // Convet argc to a smi. 1179 __ Integer32ToSmi(rdx, rdx); // Convet argc to a smi.
1179 // rax: argc 1180 // rax: argc
1180 // rdx: array_size (smi) 1181 // rdx: array_size (smi)
1181 // rdi: constructor 1182 // rdi: constructor
1182 // esp[0] : return address 1183 // esp[0] : return address
1183 // esp[8] : last argument 1184 // esp[8] : last argument
1184 AllocateJSArray(masm, 1185 AllocateJSArray(masm,
1185 rdi, 1186 rdi,
1186 rdx, 1187 rdx,
1187 rbx, 1188 rbx,
1188 rcx, 1189 rcx,
1189 r8, 1190 r8,
1190 r9, 1191 r9,
1191 false, 1192 false,
1192 call_generic_code); 1193 call_generic_code);
1193 __ IncrementCounter(&Counters::array_function_native, 1); 1194 __ IncrementCounter(COUNTERS->array_function_native(), 1);
1194 1195
1195 // rax: argc 1196 // rax: argc
1196 // rbx: JSArray 1197 // rbx: JSArray
1197 // rcx: elements_array 1198 // rcx: elements_array
1198 // r8: elements_array_end (untagged) 1199 // r8: elements_array_end (untagged)
1199 // esp[0]: return address 1200 // esp[0]: return address
1200 // esp[8]: last argument 1201 // esp[8]: last argument
1201 1202
1202 // Location of the last argument 1203 // Location of the last argument
1203 __ lea(r9, Operand(rsp, kPointerSize)); 1204 __ lea(r9, Operand(rsp, kPointerSize));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 __ CmpObjectType(rbx, MAP_TYPE, rcx); 1258 __ CmpObjectType(rbx, MAP_TYPE, rcx);
1258 __ Check(equal, "Unexpected initial map for Array function"); 1259 __ Check(equal, "Unexpected initial map for Array function");
1259 } 1260 }
1260 1261
1261 // Run the native code for the Array function called as a normal function. 1262 // Run the native code for the Array function called as a normal function.
1262 ArrayNativeCode(masm, &generic_array_code); 1263 ArrayNativeCode(masm, &generic_array_code);
1263 1264
1264 // Jump to the generic array code in case the specialized code cannot handle 1265 // Jump to the generic array code in case the specialized code cannot handle
1265 // the construction. 1266 // the construction.
1266 __ bind(&generic_array_code); 1267 __ bind(&generic_array_code);
1267 Code* code = Builtins::builtin(Builtins::ArrayCodeGeneric); 1268 Code* code = Isolate::Current()->builtins()->builtin(
1269 Builtins::ArrayCodeGeneric);
1268 Handle<Code> array_code(code); 1270 Handle<Code> array_code(code);
1269 __ Jump(array_code, RelocInfo::CODE_TARGET); 1271 __ Jump(array_code, RelocInfo::CODE_TARGET);
1270 } 1272 }
1271 1273
1272 1274
1273 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) { 1275 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) {
1274 // ----------- S t a t e ------------- 1276 // ----------- S t a t e -------------
1275 // -- rax : argc 1277 // -- rax : argc
1276 // -- rdi : constructor 1278 // -- rdi : constructor
1277 // -- rsp[0] : return address 1279 // -- rsp[0] : return address
(...skipping 13 matching lines...) Expand all
1291 __ CmpObjectType(rbx, MAP_TYPE, rcx); 1293 __ CmpObjectType(rbx, MAP_TYPE, rcx);
1292 __ Check(equal, "Unexpected initial map for Array function"); 1294 __ Check(equal, "Unexpected initial map for Array function");
1293 } 1295 }
1294 1296
1295 // Run the native code for the Array function called as constructor. 1297 // Run the native code for the Array function called as constructor.
1296 ArrayNativeCode(masm, &generic_constructor); 1298 ArrayNativeCode(masm, &generic_constructor);
1297 1299
1298 // Jump to the generic construct code in case the specialized code cannot 1300 // Jump to the generic construct code in case the specialized code cannot
1299 // handle the construction. 1301 // handle the construction.
1300 __ bind(&generic_constructor); 1302 __ bind(&generic_constructor);
1301 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); 1303 Code* code = Isolate::Current()->builtins()->builtin(
1304 Builtins::JSConstructStubGeneric);
1302 Handle<Code> generic_construct_stub(code); 1305 Handle<Code> generic_construct_stub(code);
1303 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 1306 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
1304 } 1307 }
1305 1308
1306 1309
1307 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 1310 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
1308 // TODO(849): implement custom construct stub. 1311 // TODO(849): implement custom construct stub.
1309 // Generate a copy of the generic stub for now. 1312 // Generate a copy of the generic stub for now.
1310 Generate_JSConstructStubGeneric(masm); 1313 Generate_JSConstructStubGeneric(masm);
1311 } 1314 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 1349
1347 1350
1348 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { 1351 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1349 // ----------- S t a t e ------------- 1352 // ----------- S t a t e -------------
1350 // -- rax : actual number of arguments 1353 // -- rax : actual number of arguments
1351 // -- rbx : expected number of arguments 1354 // -- rbx : expected number of arguments
1352 // -- rdx : code entry to call 1355 // -- rdx : code entry to call
1353 // ----------------------------------- 1356 // -----------------------------------
1354 1357
1355 Label invoke, dont_adapt_arguments; 1358 Label invoke, dont_adapt_arguments;
1356 __ IncrementCounter(&Counters::arguments_adaptors, 1); 1359 __ IncrementCounter(COUNTERS->arguments_adaptors(), 1);
1357 1360
1358 Label enough, too_few; 1361 Label enough, too_few;
1359 __ cmpq(rax, rbx); 1362 __ cmpq(rax, rbx);
1360 __ j(less, &too_few); 1363 __ j(less, &too_few);
1361 __ cmpq(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); 1364 __ cmpq(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
1362 __ j(equal, &dont_adapt_arguments); 1365 __ j(equal, &dont_adapt_arguments);
1363 1366
1364 { // Enough parameters: Actual >= expected. 1367 { // Enough parameters: Actual >= expected.
1365 __ bind(&enough); 1368 __ bind(&enough);
1366 EnterArgumentsAdaptorFrame(masm); 1369 EnterArgumentsAdaptorFrame(masm);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); 1483 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR);
1481 generator.Generate(); 1484 generator.Generate();
1482 } 1485 }
1483 1486
1484 1487
1485 #undef __ 1488 #undef __
1486 1489
1487 } } // namespace v8::internal 1490 } } // namespace v8::internal
1488 1491
1489 #endif // V8_TARGET_ARCH_X64 1492 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64-inl.h ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698