| 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 |