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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 } | 77 } |
78 | 78 |
79 | 79 |
80 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 80 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
81 CodeStubInterfaceDescriptor* descriptor) { | 81 CodeStubInterfaceDescriptor* descriptor) { |
82 Register registers[] = { esi, ebx, edx }; | 82 Register registers[] = { esi, ebx, edx }; |
83 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); | 83 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
84 } | 84 } |
85 | 85 |
86 | 86 |
| 87 void InstanceofStub::InitializeInterfaceDescriptor( |
| 88 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { |
| 89 Register registers[] = {esi, left(), right()}; |
| 90 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
| 91 } |
| 92 |
| 93 |
| 94 void CallFunctionStub::InitializeInterfaceDescriptor( |
| 95 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { |
| 96 Register registers[] = {esi, edi}; |
| 97 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
| 98 } |
| 99 |
| 100 |
| 101 void CallConstructStub::InitializeInterfaceDescriptor( |
| 102 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { |
| 103 // eax : number of arguments |
| 104 // ebx : feedback vector |
| 105 // edx : (only if ebx is not the megamorphic symbol) slot in feedback |
| 106 // vector (Smi) |
| 107 // edi : constructor function |
| 108 // TODO(turbofan): So far we don't gather type feedback and hence skip the |
| 109 // slot parameter, but ArrayConstructStub needs the vector to be undefined. |
| 110 Register registers[] = {esi, eax, edi, ebx}; |
| 111 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
| 112 } |
| 113 |
| 114 |
87 void RegExpConstructResultStub::InitializeInterfaceDescriptor( | 115 void RegExpConstructResultStub::InitializeInterfaceDescriptor( |
88 CodeStubInterfaceDescriptor* descriptor) { | 116 CodeStubInterfaceDescriptor* descriptor) { |
89 Register registers[] = { esi, ecx, ebx, eax }; | 117 Register registers[] = { esi, ecx, ebx, eax }; |
90 descriptor->Initialize( | 118 descriptor->Initialize( |
91 MajorKey(), ARRAY_SIZE(registers), registers, | 119 MajorKey(), ARRAY_SIZE(registers), registers, |
92 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); | 120 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); |
93 } | 121 } |
94 | 122 |
95 | 123 |
96 void TransitionElementsKindStub::InitializeInterfaceDescriptor( | 124 void TransitionElementsKindStub::InitializeInterfaceDescriptor( |
(...skipping 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2439 __ mov(object, Operand(esp, 2 * kPointerSize)); | 2467 __ mov(object, Operand(esp, 2 * kPointerSize)); |
2440 __ mov(function, Operand(esp, 1 * kPointerSize)); | 2468 __ mov(function, Operand(esp, 1 * kPointerSize)); |
2441 } | 2469 } |
2442 | 2470 |
2443 // Check that the left hand is a JS object. | 2471 // Check that the left hand is a JS object. |
2444 __ JumpIfSmi(object, ¬_js_object); | 2472 __ JumpIfSmi(object, ¬_js_object); |
2445 __ IsObjectJSObjectType(object, map, scratch, ¬_js_object); | 2473 __ IsObjectJSObjectType(object, map, scratch, ¬_js_object); |
2446 | 2474 |
2447 // If there is a call site cache don't look in the global cache, but do the | 2475 // If there is a call site cache don't look in the global cache, but do the |
2448 // real lookup and update the call site cache. | 2476 // real lookup and update the call site cache. |
2449 if (!HasCallSiteInlineCheck()) { | 2477 if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) { |
2450 // Look up the function and the map in the instanceof cache. | 2478 // Look up the function and the map in the instanceof cache. |
2451 Label miss; | 2479 Label miss; |
2452 __ CompareRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex); | 2480 __ CompareRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex); |
2453 __ j(not_equal, &miss, Label::kNear); | 2481 __ j(not_equal, &miss, Label::kNear); |
2454 __ CompareRoot(map, scratch, Heap::kInstanceofCacheMapRootIndex); | 2482 __ CompareRoot(map, scratch, Heap::kInstanceofCacheMapRootIndex); |
2455 __ j(not_equal, &miss, Label::kNear); | 2483 __ j(not_equal, &miss, Label::kNear); |
2456 __ LoadRoot(eax, Heap::kInstanceofCacheAnswerRootIndex); | 2484 __ LoadRoot(eax, Heap::kInstanceofCacheAnswerRootIndex); |
2457 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2485 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2458 __ bind(&miss); | 2486 __ bind(&miss); |
2459 } | 2487 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2498 __ cmp(scratch, Immediate(factory->null_value())); | 2526 __ cmp(scratch, Immediate(factory->null_value())); |
2499 __ j(equal, &is_not_instance, Label::kNear); | 2527 __ j(equal, &is_not_instance, Label::kNear); |
2500 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); | 2528 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); |
2501 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset)); | 2529 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset)); |
2502 __ jmp(&loop); | 2530 __ jmp(&loop); |
2503 | 2531 |
2504 __ bind(&is_instance); | 2532 __ bind(&is_instance); |
2505 if (!HasCallSiteInlineCheck()) { | 2533 if (!HasCallSiteInlineCheck()) { |
2506 __ mov(eax, Immediate(0)); | 2534 __ mov(eax, Immediate(0)); |
2507 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); | 2535 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); |
| 2536 if (ReturnTrueFalseObject()) { |
| 2537 __ mov(eax, factory->true_value()); |
| 2538 } |
2508 } else { | 2539 } else { |
2509 // Get return address and delta to inlined map check. | 2540 // Get return address and delta to inlined map check. |
2510 __ mov(eax, factory->true_value()); | 2541 __ mov(eax, factory->true_value()); |
2511 __ mov(scratch, Operand(esp, 0 * kPointerSize)); | 2542 __ mov(scratch, Operand(esp, 0 * kPointerSize)); |
2512 __ sub(scratch, Operand(esp, 1 * kPointerSize)); | 2543 __ sub(scratch, Operand(esp, 1 * kPointerSize)); |
2513 if (FLAG_debug_code) { | 2544 if (FLAG_debug_code) { |
2514 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); | 2545 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); |
2515 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); | 2546 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); |
2516 } | 2547 } |
2517 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); | 2548 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); |
2518 if (!ReturnTrueFalseObject()) { | 2549 if (!ReturnTrueFalseObject()) { |
2519 __ Move(eax, Immediate(0)); | 2550 __ Move(eax, Immediate(0)); |
2520 } | 2551 } |
2521 } | 2552 } |
2522 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2553 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2523 | 2554 |
2524 __ bind(&is_not_instance); | 2555 __ bind(&is_not_instance); |
2525 if (!HasCallSiteInlineCheck()) { | 2556 if (!HasCallSiteInlineCheck()) { |
2526 __ mov(eax, Immediate(Smi::FromInt(1))); | 2557 __ mov(eax, Immediate(Smi::FromInt(1))); |
2527 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); | 2558 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); |
| 2559 if (ReturnTrueFalseObject()) { |
| 2560 __ mov(eax, factory->false_value()); |
| 2561 } |
2528 } else { | 2562 } else { |
2529 // Get return address and delta to inlined map check. | 2563 // Get return address and delta to inlined map check. |
2530 __ mov(eax, factory->false_value()); | 2564 __ mov(eax, factory->false_value()); |
2531 __ mov(scratch, Operand(esp, 0 * kPointerSize)); | 2565 __ mov(scratch, Operand(esp, 0 * kPointerSize)); |
2532 __ sub(scratch, Operand(esp, 1 * kPointerSize)); | 2566 __ sub(scratch, Operand(esp, 1 * kPointerSize)); |
2533 if (FLAG_debug_code) { | 2567 if (FLAG_debug_code) { |
2534 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); | 2568 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); |
2535 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); | 2569 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); |
2536 } | 2570 } |
2537 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); | 2571 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); |
2538 if (!ReturnTrueFalseObject()) { | 2572 if (!ReturnTrueFalseObject()) { |
2539 __ Move(eax, Immediate(Smi::FromInt(1))); | 2573 __ Move(eax, Immediate(Smi::FromInt(1))); |
2540 } | 2574 } |
2541 } | 2575 } |
2542 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2576 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2543 | 2577 |
2544 Label object_not_null, object_not_null_or_smi; | 2578 Label object_not_null, object_not_null_or_smi; |
2545 __ bind(¬_js_object); | 2579 __ bind(¬_js_object); |
2546 // Before null, smi and string value checks, check that the rhs is a function | 2580 // Before null, smi and string value checks, check that the rhs is a function |
2547 // as for a non-function rhs an exception needs to be thrown. | 2581 // as for a non-function rhs an exception needs to be thrown. |
2548 __ JumpIfSmi(function, &slow, Label::kNear); | 2582 __ JumpIfSmi(function, &slow, Label::kNear); |
2549 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); | 2583 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); |
2550 __ j(not_equal, &slow, Label::kNear); | 2584 __ j(not_equal, &slow, Label::kNear); |
2551 | 2585 |
2552 // Null is not instance of anything. | 2586 // Null is not instance of anything. |
2553 __ cmp(object, factory->null_value()); | 2587 __ cmp(object, factory->null_value()); |
2554 __ j(not_equal, &object_not_null, Label::kNear); | 2588 __ j(not_equal, &object_not_null, Label::kNear); |
2555 __ Move(eax, Immediate(Smi::FromInt(1))); | 2589 if (ReturnTrueFalseObject()) { |
| 2590 __ mov(eax, factory->false_value()); |
| 2591 } else { |
| 2592 __ Move(eax, Immediate(Smi::FromInt(1))); |
| 2593 } |
2556 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2594 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2557 | 2595 |
2558 __ bind(&object_not_null); | 2596 __ bind(&object_not_null); |
2559 // Smi values is not instance of anything. | 2597 // Smi values is not instance of anything. |
2560 __ JumpIfNotSmi(object, &object_not_null_or_smi, Label::kNear); | 2598 __ JumpIfNotSmi(object, &object_not_null_or_smi, Label::kNear); |
2561 __ Move(eax, Immediate(Smi::FromInt(1))); | 2599 if (ReturnTrueFalseObject()) { |
| 2600 __ mov(eax, factory->false_value()); |
| 2601 } else { |
| 2602 __ Move(eax, Immediate(Smi::FromInt(1))); |
| 2603 } |
2562 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2604 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2563 | 2605 |
2564 __ bind(&object_not_null_or_smi); | 2606 __ bind(&object_not_null_or_smi); |
2565 // String values is not instance of anything. | 2607 // String values is not instance of anything. |
2566 Condition is_string = masm->IsObjectStringType(object, scratch, scratch); | 2608 Condition is_string = masm->IsObjectStringType(object, scratch, scratch); |
2567 __ j(NegateCondition(is_string), &slow, Label::kNear); | 2609 __ j(NegateCondition(is_string), &slow, Label::kNear); |
2568 __ Move(eax, Immediate(Smi::FromInt(1))); | 2610 if (ReturnTrueFalseObject()) { |
| 2611 __ mov(eax, factory->false_value()); |
| 2612 } else { |
| 2613 __ Move(eax, Immediate(Smi::FromInt(1))); |
| 2614 } |
2569 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2615 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2570 | 2616 |
2571 // Slow-case: Go through the JavaScript implementation. | 2617 // Slow-case: Go through the JavaScript implementation. |
2572 __ bind(&slow); | 2618 __ bind(&slow); |
2573 if (!ReturnTrueFalseObject()) { | 2619 if (!ReturnTrueFalseObject()) { |
2574 // Tail call the builtin which returns 0 or 1. | 2620 // Tail call the builtin which returns 0 or 1. |
2575 if (HasArgsInRegisters()) { | 2621 if (HasArgsInRegisters()) { |
2576 // Push arguments below return address. | 2622 // Push arguments below return address. |
2577 __ pop(scratch); | 2623 __ pop(scratch); |
2578 __ push(object); | 2624 __ push(object); |
(...skipping 2027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4606 Operand(ebp, 7 * kPointerSize), | 4652 Operand(ebp, 7 * kPointerSize), |
4607 NULL); | 4653 NULL); |
4608 } | 4654 } |
4609 | 4655 |
4610 | 4656 |
4611 #undef __ | 4657 #undef __ |
4612 | 4658 |
4613 } } // namespace v8::internal | 4659 } } // namespace v8::internal |
4614 | 4660 |
4615 #endif // V8_TARGET_ARCH_X87 | 4661 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |