OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 } | 1422 } |
1423 | 1423 |
1424 static void IncrementCallCount(MacroAssembler* masm, Register feedback_vector, | 1424 static void IncrementCallCount(MacroAssembler* masm, Register feedback_vector, |
1425 Register slot) { | 1425 Register slot) { |
1426 __ add(FieldOperand(feedback_vector, slot, times_half_pointer_size, | 1426 __ add(FieldOperand(feedback_vector, slot, times_half_pointer_size, |
1427 FixedArray::kHeaderSize + kPointerSize), | 1427 FixedArray::kHeaderSize + kPointerSize), |
1428 Immediate(Smi::FromInt(1))); | 1428 Immediate(Smi::FromInt(1))); |
1429 } | 1429 } |
1430 | 1430 |
1431 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { | 1431 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { |
| 1432 // eax - number of arguments |
1432 // edi - function | 1433 // edi - function |
1433 // edx - slot id | 1434 // edx - slot id |
1434 // ebx - vector | 1435 // ebx - vector |
1435 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 1436 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
1436 __ cmp(edi, ecx); | 1437 __ cmp(edi, ecx); |
1437 __ j(not_equal, miss); | 1438 __ j(not_equal, miss); |
1438 | 1439 |
1439 __ mov(eax, arg_count()); | |
1440 // Reload ecx. | 1440 // Reload ecx. |
1441 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 1441 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
1442 FixedArray::kHeaderSize)); | 1442 FixedArray::kHeaderSize)); |
1443 | 1443 |
1444 // Increment the call count for monomorphic function calls. | 1444 // Increment the call count for monomorphic function calls. |
1445 IncrementCallCount(masm, ebx, edx); | 1445 IncrementCallCount(masm, ebx, edx); |
1446 | 1446 |
1447 __ mov(ebx, ecx); | 1447 __ mov(ebx, ecx); |
1448 __ mov(edx, edi); | 1448 __ mov(edx, edi); |
1449 ArrayConstructorStub stub(masm->isolate()); | 1449 ArrayConstructorStub stub(masm->isolate()); |
1450 __ TailCallStub(&stub); | 1450 __ TailCallStub(&stub); |
1451 | 1451 |
1452 // Unreachable. | 1452 // Unreachable. |
1453 } | 1453 } |
1454 | 1454 |
1455 | 1455 |
1456 void CallICStub::Generate(MacroAssembler* masm) { | 1456 void CallICStub::Generate(MacroAssembler* masm) { |
| 1457 // edi - number of arguments |
1457 // edi - function | 1458 // edi - function |
1458 // edx - slot id | 1459 // edx - slot id |
1459 // ebx - vector | 1460 // ebx - vector |
1460 Isolate* isolate = masm->isolate(); | 1461 Isolate* isolate = masm->isolate(); |
1461 Label extra_checks_or_miss, call, call_function, call_count_incremented; | 1462 Label extra_checks_or_miss, call, call_function, call_count_incremented; |
1462 int argc = arg_count(); | |
1463 ParameterCount actual(argc); | |
1464 | 1463 |
1465 // The checks. First, does edi match the recorded monomorphic target? | 1464 // The checks. First, does edi match the recorded monomorphic target? |
1466 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 1465 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
1467 FixedArray::kHeaderSize)); | 1466 FixedArray::kHeaderSize)); |
1468 | 1467 |
1469 // We don't know that we have a weak cell. We might have a private symbol | 1468 // We don't know that we have a weak cell. We might have a private symbol |
1470 // or an AllocationSite, but the memory is safe to examine. | 1469 // or an AllocationSite, but the memory is safe to examine. |
1471 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to | 1470 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to |
1472 // FixedArray. | 1471 // FixedArray. |
1473 // WeakCell::kValueOffset - contains a JSFunction or Smi(0) | 1472 // WeakCell::kValueOffset - contains a JSFunction or Smi(0) |
(...skipping 11 matching lines...) Expand all Loading... |
1485 | 1484 |
1486 // The compare above could have been a SMI/SMI comparison. Guard against this | 1485 // The compare above could have been a SMI/SMI comparison. Guard against this |
1487 // convincing us that we have a monomorphic JSFunction. | 1486 // convincing us that we have a monomorphic JSFunction. |
1488 __ JumpIfSmi(edi, &extra_checks_or_miss); | 1487 __ JumpIfSmi(edi, &extra_checks_or_miss); |
1489 | 1488 |
1490 __ bind(&call_function); | 1489 __ bind(&call_function); |
1491 | 1490 |
1492 // Increment the call count for monomorphic function calls. | 1491 // Increment the call count for monomorphic function calls. |
1493 IncrementCallCount(masm, ebx, edx); | 1492 IncrementCallCount(masm, ebx, edx); |
1494 | 1493 |
1495 __ Set(eax, argc); | |
1496 __ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(), | 1494 __ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(), |
1497 tail_call_mode()), | 1495 tail_call_mode()), |
1498 RelocInfo::CODE_TARGET); | 1496 RelocInfo::CODE_TARGET); |
1499 | 1497 |
1500 __ bind(&extra_checks_or_miss); | 1498 __ bind(&extra_checks_or_miss); |
1501 Label uninitialized, miss, not_allocation_site; | 1499 Label uninitialized, miss, not_allocation_site; |
1502 | 1500 |
1503 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 1501 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
1504 __ j(equal, &call); | 1502 __ j(equal, &call); |
1505 | 1503 |
(...skipping 25 matching lines...) Expand all Loading... |
1531 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), | 1529 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), |
1532 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 1530 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
1533 | 1531 |
1534 __ bind(&call); | 1532 __ bind(&call); |
1535 | 1533 |
1536 // Increment the call count for megamorphic function calls. | 1534 // Increment the call count for megamorphic function calls. |
1537 IncrementCallCount(masm, ebx, edx); | 1535 IncrementCallCount(masm, ebx, edx); |
1538 | 1536 |
1539 __ bind(&call_count_incremented); | 1537 __ bind(&call_count_incremented); |
1540 | 1538 |
1541 __ Set(eax, argc); | |
1542 __ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()), | 1539 __ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()), |
1543 RelocInfo::CODE_TARGET); | 1540 RelocInfo::CODE_TARGET); |
1544 | 1541 |
1545 __ bind(&uninitialized); | 1542 __ bind(&uninitialized); |
1546 | 1543 |
1547 // We are going monomorphic, provided we actually have a JSFunction. | 1544 // We are going monomorphic, provided we actually have a JSFunction. |
1548 __ JumpIfSmi(edi, &miss); | 1545 __ JumpIfSmi(edi, &miss); |
1549 | 1546 |
1550 // Goto miss case if we do not have a function. | 1547 // Goto miss case if we do not have a function. |
1551 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 1548 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
1552 __ j(not_equal, &miss); | 1549 __ j(not_equal, &miss); |
1553 | 1550 |
1554 // Make sure the function is not the Array() function, which requires special | 1551 // Make sure the function is not the Array() function, which requires special |
1555 // behavior on MISS. | 1552 // behavior on MISS. |
1556 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 1553 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
1557 __ cmp(edi, ecx); | 1554 __ cmp(edi, ecx); |
1558 __ j(equal, &miss); | 1555 __ j(equal, &miss); |
1559 | 1556 |
1560 // Make sure the function belongs to the same native context. | 1557 // Make sure the function belongs to the same native context. |
1561 __ mov(ecx, FieldOperand(edi, JSFunction::kContextOffset)); | 1558 __ mov(ecx, FieldOperand(edi, JSFunction::kContextOffset)); |
1562 __ mov(ecx, ContextOperand(ecx, Context::NATIVE_CONTEXT_INDEX)); | 1559 __ mov(ecx, ContextOperand(ecx, Context::NATIVE_CONTEXT_INDEX)); |
1563 __ cmp(ecx, NativeContextOperand()); | 1560 __ cmp(ecx, NativeContextOperand()); |
1564 __ j(not_equal, &miss); | 1561 __ j(not_equal, &miss); |
1565 | 1562 |
1566 // Store the function. Use a stub since we need a frame for allocation. | 1563 // Store the function. Use a stub since we need a frame for allocation. |
| 1564 // eax - number of arguments |
1567 // ebx - vector | 1565 // ebx - vector |
1568 // edx - slot | 1566 // edx - slot |
1569 // edi - function | 1567 // edi - function |
1570 { | 1568 { |
1571 FrameScope scope(masm, StackFrame::INTERNAL); | 1569 FrameScope scope(masm, StackFrame::INTERNAL); |
1572 CreateWeakCellStub create_stub(isolate); | 1570 CreateWeakCellStub create_stub(isolate); |
| 1571 __ SmiTag(eax); |
| 1572 __ push(eax); |
1573 __ push(ebx); | 1573 __ push(ebx); |
1574 __ push(edx); | 1574 __ push(edx); |
1575 __ push(edi); | 1575 __ push(edi); |
1576 __ push(esi); | 1576 __ push(esi); |
1577 __ CallStub(&create_stub); | 1577 __ CallStub(&create_stub); |
1578 __ pop(esi); | 1578 __ pop(esi); |
1579 __ pop(edi); | 1579 __ pop(edi); |
1580 __ pop(edx); | 1580 __ pop(edx); |
1581 __ pop(ebx); | 1581 __ pop(ebx); |
| 1582 __ pop(eax); |
| 1583 __ SmiUntag(eax); |
1582 } | 1584 } |
1583 | 1585 |
1584 __ jmp(&call_function); | 1586 __ jmp(&call_function); |
1585 | 1587 |
1586 // We are here because tracing is on or we encountered a MISS case we can't | 1588 // We are here because tracing is on or we encountered a MISS case we can't |
1587 // handle here. | 1589 // handle here. |
1588 __ bind(&miss); | 1590 __ bind(&miss); |
1589 GenerateMiss(masm); | 1591 GenerateMiss(masm); |
1590 | 1592 |
1591 __ jmp(&call_count_incremented); | 1593 __ jmp(&call_count_incremented); |
1592 | 1594 |
1593 // Unreachable | 1595 // Unreachable |
1594 __ int3(); | 1596 __ int3(); |
1595 } | 1597 } |
1596 | 1598 |
1597 | 1599 |
1598 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 1600 void CallICStub::GenerateMiss(MacroAssembler* masm) { |
1599 FrameScope scope(masm, StackFrame::INTERNAL); | 1601 FrameScope scope(masm, StackFrame::INTERNAL); |
1600 | 1602 |
| 1603 // Preserve the number of arguments. |
| 1604 __ SmiTag(eax); |
| 1605 __ push(eax); |
| 1606 |
1601 // Push the function and feedback info. | 1607 // Push the function and feedback info. |
1602 __ push(edi); | 1608 __ push(edi); |
1603 __ push(ebx); | 1609 __ push(ebx); |
1604 __ push(edx); | 1610 __ push(edx); |
1605 | 1611 |
1606 // Call the entry. | 1612 // Call the entry. |
1607 __ CallRuntime(Runtime::kCallIC_Miss); | 1613 __ CallRuntime(Runtime::kCallIC_Miss); |
1608 | 1614 |
1609 // Move result to edi and exit the internal frame. | 1615 // Move result to edi and exit the internal frame. |
1610 __ mov(edi, eax); | 1616 __ mov(edi, eax); |
| 1617 |
| 1618 // Restore number of arguments. |
| 1619 __ pop(eax); |
| 1620 __ SmiUntag(eax); |
1611 } | 1621 } |
1612 | 1622 |
1613 | 1623 |
1614 bool CEntryStub::NeedsImmovableCode() { | 1624 bool CEntryStub::NeedsImmovableCode() { |
1615 return false; | 1625 return false; |
1616 } | 1626 } |
1617 | 1627 |
1618 | 1628 |
1619 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 1629 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
1620 CEntryStub::GenerateAheadOfTime(isolate); | 1630 CEntryStub::GenerateAheadOfTime(isolate); |
(...skipping 3555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5176 kStackUnwindSpace, nullptr, return_value_operand, | 5186 kStackUnwindSpace, nullptr, return_value_operand, |
5177 NULL); | 5187 NULL); |
5178 } | 5188 } |
5179 | 5189 |
5180 #undef __ | 5190 #undef __ |
5181 | 5191 |
5182 } // namespace internal | 5192 } // namespace internal |
5183 } // namespace v8 | 5193 } // namespace v8 |
5184 | 5194 |
5185 #endif // V8_TARGET_ARCH_IA32 | 5195 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |