OLD | NEW |
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 num_extra_args = 1; | 62 num_extra_args = 1; |
63 __ PopReturnAddressTo(kScratchRegister); | 63 __ PopReturnAddressTo(kScratchRegister); |
64 __ Push(rdi); | 64 __ Push(rdi); |
65 __ PushReturnAddressFrom(kScratchRegister); | 65 __ PushReturnAddressFrom(kScratchRegister); |
66 } else { | 66 } else { |
67 ASSERT(extra_args == NO_EXTRA_ARGUMENTS); | 67 ASSERT(extra_args == NO_EXTRA_ARGUMENTS); |
68 } | 68 } |
69 | 69 |
70 // JumpToExternalReference expects rax to contain the number of arguments | 70 // JumpToExternalReference expects rax to contain the number of arguments |
71 // including the receiver and the extra arguments. | 71 // including the receiver and the extra arguments. |
72 __ addq(rax, Immediate(num_extra_args + 1)); | 72 __ addp(rax, Immediate(num_extra_args + 1)); |
73 __ JumpToExternalReference(ExternalReference(id, masm->isolate()), 1); | 73 __ JumpToExternalReference(ExternalReference(id, masm->isolate()), 1); |
74 } | 74 } |
75 | 75 |
76 | 76 |
77 static void CallRuntimePassFunction( | 77 static void CallRuntimePassFunction( |
78 MacroAssembler* masm, Runtime::FunctionId function_id) { | 78 MacroAssembler* masm, Runtime::FunctionId function_id) { |
79 FrameScope scope(masm, StackFrame::INTERNAL); | 79 FrameScope scope(masm, StackFrame::INTERNAL); |
80 // Push a copy of the function onto the stack. | 80 // Push a copy of the function onto the stack. |
81 __ Push(rdi); | 81 __ Push(rdi); |
82 // Function is also the parameter to the runtime call. | 82 // Function is also the parameter to the runtime call. |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 | 282 |
283 // Check if a non-empty properties array is needed. | 283 // Check if a non-empty properties array is needed. |
284 // Allocate and initialize a FixedArray if it is. | 284 // Allocate and initialize a FixedArray if it is. |
285 // rax: initial map | 285 // rax: initial map |
286 // rbx: JSObject | 286 // rbx: JSObject |
287 // rdi: start of next object | 287 // rdi: start of next object |
288 // Calculate total properties described map. | 288 // Calculate total properties described map. |
289 __ movzxbq(rdx, FieldOperand(rax, Map::kUnusedPropertyFieldsOffset)); | 289 __ movzxbq(rdx, FieldOperand(rax, Map::kUnusedPropertyFieldsOffset)); |
290 __ movzxbq(rcx, | 290 __ movzxbq(rcx, |
291 FieldOperand(rax, Map::kPreAllocatedPropertyFieldsOffset)); | 291 FieldOperand(rax, Map::kPreAllocatedPropertyFieldsOffset)); |
292 __ addq(rdx, rcx); | 292 __ addp(rdx, rcx); |
293 // Calculate unused properties past the end of the in-object properties. | 293 // Calculate unused properties past the end of the in-object properties. |
294 __ movzxbq(rcx, FieldOperand(rax, Map::kInObjectPropertiesOffset)); | 294 __ movzxbq(rcx, FieldOperand(rax, Map::kInObjectPropertiesOffset)); |
295 __ subq(rdx, rcx); | 295 __ subp(rdx, rcx); |
296 // Done if no extra properties are to be allocated. | 296 // Done if no extra properties are to be allocated. |
297 __ j(zero, &allocated); | 297 __ j(zero, &allocated); |
298 __ Assert(positive, kPropertyAllocationCountFailed); | 298 __ Assert(positive, kPropertyAllocationCountFailed); |
299 | 299 |
300 // Scale the number of elements by pointer size and add the header for | 300 // Scale the number of elements by pointer size and add the header for |
301 // FixedArrays to the start of the next object calculation from above. | 301 // FixedArrays to the start of the next object calculation from above. |
302 // rbx: JSObject | 302 // rbx: JSObject |
303 // rdi: start of next object (will be start of FixedArray) | 303 // rdi: start of next object (will be start of FixedArray) |
304 // rdx: number of elements in properties array | 304 // rdx: number of elements in properties array |
305 __ Allocate(FixedArray::kHeaderSize, | 305 __ Allocate(FixedArray::kHeaderSize, |
(...skipping 19 matching lines...) Expand all Loading... |
325 // rbx: JSObject | 325 // rbx: JSObject |
326 // rdi: FixedArray | 326 // rdi: FixedArray |
327 // rax: start of next object | 327 // rax: start of next object |
328 // rdx: number of elements | 328 // rdx: number of elements |
329 { Label loop, entry; | 329 { Label loop, entry; |
330 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 330 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
331 __ lea(rcx, Operand(rdi, FixedArray::kHeaderSize)); | 331 __ lea(rcx, Operand(rdi, FixedArray::kHeaderSize)); |
332 __ jmp(&entry); | 332 __ jmp(&entry); |
333 __ bind(&loop); | 333 __ bind(&loop); |
334 __ movp(Operand(rcx, 0), rdx); | 334 __ movp(Operand(rcx, 0), rdx); |
335 __ addq(rcx, Immediate(kPointerSize)); | 335 __ addp(rcx, Immediate(kPointerSize)); |
336 __ bind(&entry); | 336 __ bind(&entry); |
337 __ cmpq(rcx, rax); | 337 __ cmpq(rcx, rax); |
338 __ j(below, &loop); | 338 __ j(below, &loop); |
339 } | 339 } |
340 | 340 |
341 // Store the initialized FixedArray into the properties field of | 341 // Store the initialized FixedArray into the properties field of |
342 // the JSObject | 342 // the JSObject |
343 // rbx: JSObject | 343 // rbx: JSObject |
344 // rdi: FixedArray | 344 // rdi: FixedArray |
345 __ or_(rdi, Immediate(kHeapObjectTag)); // add the heap tag | 345 __ or_(rdi, Immediate(kHeapObjectTag)); // add the heap tag |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 | 583 |
584 // Copy arguments to the stack in a loop. | 584 // Copy arguments to the stack in a loop. |
585 // Register rbx points to array of pointers to handle locations. | 585 // Register rbx points to array of pointers to handle locations. |
586 // Push the values of these handles. | 586 // Push the values of these handles. |
587 Label loop, entry; | 587 Label loop, entry; |
588 __ Set(rcx, 0); // Set loop variable to 0. | 588 __ Set(rcx, 0); // Set loop variable to 0. |
589 __ jmp(&entry); | 589 __ jmp(&entry); |
590 __ bind(&loop); | 590 __ bind(&loop); |
591 __ movp(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0)); | 591 __ movp(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0)); |
592 __ Push(Operand(kScratchRegister, 0)); // dereference handle | 592 __ Push(Operand(kScratchRegister, 0)); // dereference handle |
593 __ addq(rcx, Immediate(1)); | 593 __ addp(rcx, Immediate(1)); |
594 __ bind(&entry); | 594 __ bind(&entry); |
595 __ cmpq(rcx, rax); | 595 __ cmpq(rcx, rax); |
596 __ j(not_equal, &loop); | 596 __ j(not_equal, &loop); |
597 | 597 |
598 // Invoke the code. | 598 // Invoke the code. |
599 if (is_construct) { | 599 if (is_construct) { |
600 // No type feedback cell is available | 600 // No type feedback cell is available |
601 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 601 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
602 // Expects rdi to hold function pointer. | 602 // Expects rdi to hold function pointer. |
603 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); | 603 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 | 663 |
664 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { | 664 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { |
665 // For now, we are relying on the fact that make_code_young doesn't do any | 665 // For now, we are relying on the fact that make_code_young doesn't do any |
666 // garbage collection which allows us to save/restore the registers without | 666 // garbage collection which allows us to save/restore the registers without |
667 // worrying about which of them contain pointers. We also don't build an | 667 // worrying about which of them contain pointers. We also don't build an |
668 // internal frame to make the code faster, since we shouldn't have to do stack | 668 // internal frame to make the code faster, since we shouldn't have to do stack |
669 // crawls in MakeCodeYoung. This seems a bit fragile. | 669 // crawls in MakeCodeYoung. This seems a bit fragile. |
670 | 670 |
671 // Re-execute the code that was patched back to the young age when | 671 // Re-execute the code that was patched back to the young age when |
672 // the stub returns. | 672 // the stub returns. |
673 __ subq(Operand(rsp, 0), Immediate(5)); | 673 __ subp(Operand(rsp, 0), Immediate(5)); |
674 __ Pushad(); | 674 __ Pushad(); |
675 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); | 675 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); |
676 __ movp(arg_reg_1, Operand(rsp, kNumSafepointRegisters * kPointerSize)); | 676 __ movp(arg_reg_1, Operand(rsp, kNumSafepointRegisters * kPointerSize)); |
677 { // NOLINT | 677 { // NOLINT |
678 FrameScope scope(masm, StackFrame::MANUAL); | 678 FrameScope scope(masm, StackFrame::MANUAL); |
679 __ PrepareCallCFunction(2); | 679 __ PrepareCallCFunction(2); |
680 __ CallCFunction( | 680 __ CallCFunction( |
681 ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 681 ExternalReference::get_make_code_young_function(masm->isolate()), 2); |
682 } | 682 } |
683 __ Popad(); | 683 __ Popad(); |
(...skipping 15 matching lines...) Expand all Loading... |
699 | 699 |
700 | 700 |
701 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { | 701 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { |
702 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact | 702 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact |
703 // that make_code_young doesn't do any garbage collection which allows us to | 703 // that make_code_young doesn't do any garbage collection which allows us to |
704 // save/restore the registers without worrying about which of them contain | 704 // save/restore the registers without worrying about which of them contain |
705 // pointers. | 705 // pointers. |
706 __ Pushad(); | 706 __ Pushad(); |
707 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); | 707 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); |
708 __ movp(arg_reg_1, Operand(rsp, kNumSafepointRegisters * kPointerSize)); | 708 __ movp(arg_reg_1, Operand(rsp, kNumSafepointRegisters * kPointerSize)); |
709 __ subq(arg_reg_1, Immediate(Assembler::kShortCallInstructionLength)); | 709 __ subp(arg_reg_1, Immediate(Assembler::kShortCallInstructionLength)); |
710 { // NOLINT | 710 { // NOLINT |
711 FrameScope scope(masm, StackFrame::MANUAL); | 711 FrameScope scope(masm, StackFrame::MANUAL); |
712 __ PrepareCallCFunction(2); | 712 __ PrepareCallCFunction(2); |
713 __ CallCFunction( | 713 __ CallCFunction( |
714 ExternalReference::get_mark_code_as_executed_function(masm->isolate()), | 714 ExternalReference::get_mark_code_as_executed_function(masm->isolate()), |
715 2); | 715 2); |
716 } | 716 } |
717 __ Popad(); | 717 __ Popad(); |
718 | 718 |
719 // Perform prologue operations usually performed by the young code stub. | 719 // Perform prologue operations usually performed by the young code stub. |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1000 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1001 | 1001 |
1002 // Check the stack for overflow. We are not trying to catch | 1002 // Check the stack for overflow. We are not trying to catch |
1003 // interruptions (e.g. debug break and preemption) here, so the "real stack | 1003 // interruptions (e.g. debug break and preemption) here, so the "real stack |
1004 // limit" is checked. | 1004 // limit" is checked. |
1005 Label okay; | 1005 Label okay; |
1006 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); | 1006 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); |
1007 __ movp(rcx, rsp); | 1007 __ movp(rcx, rsp); |
1008 // Make rcx the space we have left. The stack might already be overflowed | 1008 // Make rcx the space we have left. The stack might already be overflowed |
1009 // here which will cause rcx to become negative. | 1009 // here which will cause rcx to become negative. |
1010 __ subq(rcx, kScratchRegister); | 1010 __ subp(rcx, kScratchRegister); |
1011 // Make rdx the space we need for the array when it is unrolled onto the | 1011 // Make rdx the space we need for the array when it is unrolled onto the |
1012 // stack. | 1012 // stack. |
1013 __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rax, kPointerSizeLog2); | 1013 __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rax, kPointerSizeLog2); |
1014 // Check if the arguments will overflow the stack. | 1014 // Check if the arguments will overflow the stack. |
1015 __ cmpq(rcx, rdx); | 1015 __ cmpq(rcx, rdx); |
1016 __ j(greater, &okay); // Signed comparison. | 1016 __ j(greater, &okay); // Signed comparison. |
1017 | 1017 |
1018 // Out of stack space. | 1018 // Out of stack space. |
1019 __ Push(Operand(rbp, kFunctionOffset)); | 1019 __ Push(Operand(rbp, kFunctionOffset)); |
1020 __ Push(rax); | 1020 __ Push(rax); |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 | 1381 |
1382 // Copy receiver and all expected arguments. | 1382 // Copy receiver and all expected arguments. |
1383 const int offset = StandardFrameConstants::kCallerSPOffset; | 1383 const int offset = StandardFrameConstants::kCallerSPOffset; |
1384 __ lea(rax, Operand(rbp, rax, times_pointer_size, offset)); | 1384 __ lea(rax, Operand(rbp, rax, times_pointer_size, offset)); |
1385 __ Set(r8, -1); // account for receiver | 1385 __ Set(r8, -1); // account for receiver |
1386 | 1386 |
1387 Label copy; | 1387 Label copy; |
1388 __ bind(©); | 1388 __ bind(©); |
1389 __ incq(r8); | 1389 __ incq(r8); |
1390 __ Push(Operand(rax, 0)); | 1390 __ Push(Operand(rax, 0)); |
1391 __ subq(rax, Immediate(kPointerSize)); | 1391 __ subp(rax, Immediate(kPointerSize)); |
1392 __ cmpq(r8, rbx); | 1392 __ cmpq(r8, rbx); |
1393 __ j(less, ©); | 1393 __ j(less, ©); |
1394 __ jmp(&invoke); | 1394 __ jmp(&invoke); |
1395 } | 1395 } |
1396 | 1396 |
1397 { // Too few parameters: Actual < expected. | 1397 { // Too few parameters: Actual < expected. |
1398 __ bind(&too_few); | 1398 __ bind(&too_few); |
1399 EnterArgumentsAdaptorFrame(masm); | 1399 EnterArgumentsAdaptorFrame(masm); |
1400 | 1400 |
1401 // Copy receiver and all actual arguments. | 1401 // Copy receiver and all actual arguments. |
1402 const int offset = StandardFrameConstants::kCallerSPOffset; | 1402 const int offset = StandardFrameConstants::kCallerSPOffset; |
1403 __ lea(rdi, Operand(rbp, rax, times_pointer_size, offset)); | 1403 __ lea(rdi, Operand(rbp, rax, times_pointer_size, offset)); |
1404 __ Set(r8, -1); // account for receiver | 1404 __ Set(r8, -1); // account for receiver |
1405 | 1405 |
1406 Label copy; | 1406 Label copy; |
1407 __ bind(©); | 1407 __ bind(©); |
1408 __ incq(r8); | 1408 __ incq(r8); |
1409 __ Push(Operand(rdi, 0)); | 1409 __ Push(Operand(rdi, 0)); |
1410 __ subq(rdi, Immediate(kPointerSize)); | 1410 __ subp(rdi, Immediate(kPointerSize)); |
1411 __ cmpq(r8, rax); | 1411 __ cmpq(r8, rax); |
1412 __ j(less, ©); | 1412 __ j(less, ©); |
1413 | 1413 |
1414 // Fill remaining expected arguments with undefined values. | 1414 // Fill remaining expected arguments with undefined values. |
1415 Label fill; | 1415 Label fill; |
1416 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); | 1416 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); |
1417 __ bind(&fill); | 1417 __ bind(&fill); |
1418 __ incq(r8); | 1418 __ incq(r8); |
1419 __ Push(kScratchRegister); | 1419 __ Push(kScratchRegister); |
1420 __ cmpq(r8, rbx); | 1420 __ cmpq(r8, rbx); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1494 __ bind(&ok); | 1494 __ bind(&ok); |
1495 __ ret(0); | 1495 __ ret(0); |
1496 } | 1496 } |
1497 | 1497 |
1498 | 1498 |
1499 #undef __ | 1499 #undef __ |
1500 | 1500 |
1501 } } // namespace v8::internal | 1501 } } // namespace v8::internal |
1502 | 1502 |
1503 #endif // V8_TARGET_ARCH_X64 | 1503 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |