| 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/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 | 326 |
| 327 void MathPowStub::Generate(MacroAssembler* masm) { | 327 void MathPowStub::Generate(MacroAssembler* masm) { |
| 328 // No SSE2 support | 328 // No SSE2 support |
| 329 UNREACHABLE(); | 329 UNREACHABLE(); |
| 330 } | 330 } |
| 331 | 331 |
| 332 | 332 |
| 333 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { | 333 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { |
| 334 Label miss; | 334 Label miss; |
| 335 Register receiver = LoadDescriptor::ReceiverRegister(); | 335 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 336 // With careful management, we won't have to save slot and vector on |
| 337 // the stack. Simply handle the possibly missing case first. |
| 338 // TODO(mvstanton): this code can be more efficient. |
| 339 __ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset), |
| 340 Immediate(isolate()->factory()->the_hole_value())); |
| 341 __ j(equal, &miss); |
| 342 __ TryGetFunctionPrototype(receiver, eax, ebx, &miss); |
| 343 __ ret(0); |
| 336 | 344 |
| 337 if (FLAG_vector_ics) { | |
| 338 // With careful management, we won't have to save slot and vector on | |
| 339 // the stack. Simply handle the possibly missing case first. | |
| 340 // TODO(mvstanton): this code can be more efficient. | |
| 341 __ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset), | |
| 342 Immediate(isolate()->factory()->the_hole_value())); | |
| 343 __ j(equal, &miss); | |
| 344 __ TryGetFunctionPrototype(receiver, eax, ebx, &miss); | |
| 345 __ ret(0); | |
| 346 } else { | |
| 347 NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, eax, | |
| 348 ebx, &miss); | |
| 349 } | |
| 350 __ bind(&miss); | 345 __ bind(&miss); |
| 351 PropertyAccessCompiler::TailCallBuiltin( | 346 PropertyAccessCompiler::TailCallBuiltin( |
| 352 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); | 347 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); |
| 353 } | 348 } |
| 354 | 349 |
| 355 | 350 |
| 356 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 351 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
| 357 // Return address is on the stack. | 352 // Return address is on the stack. |
| 358 Label slow; | 353 Label slow; |
| 359 | 354 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 386 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { | 381 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { |
| 387 // Return address is on the stack. | 382 // Return address is on the stack. |
| 388 Label miss; | 383 Label miss; |
| 389 | 384 |
| 390 Register receiver = LoadDescriptor::ReceiverRegister(); | 385 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 391 Register index = LoadDescriptor::NameRegister(); | 386 Register index = LoadDescriptor::NameRegister(); |
| 392 Register scratch = edi; | 387 Register scratch = edi; |
| 393 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 388 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 394 Register result = eax; | 389 Register result = eax; |
| 395 DCHECK(!result.is(scratch)); | 390 DCHECK(!result.is(scratch)); |
| 396 DCHECK(!FLAG_vector_ics || | 391 DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()) && |
| 397 (!scratch.is(VectorLoadICDescriptor::VectorRegister()) && | 392 result.is(VectorLoadICDescriptor::SlotRegister())); |
| 398 result.is(VectorLoadICDescriptor::SlotRegister()))); | |
| 399 | 393 |
| 400 // StringCharAtGenerator doesn't use the result register until it's passed | 394 // StringCharAtGenerator doesn't use the result register until it's passed |
| 401 // the different miss possibilities. If it did, we would have a conflict | 395 // the different miss possibilities. If it did, we would have a conflict |
| 402 // when FLAG_vector_ics is true. | 396 // when FLAG_vector_ics is true. |
| 403 | 397 |
| 404 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | 398 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, |
| 405 &miss, // When not a string. | 399 &miss, // When not a string. |
| 406 &miss, // When not a number. | 400 &miss, // When not a number. |
| 407 &miss, // When index out of range. | 401 &miss, // When index out of range. |
| 408 STRING_INDEX_IS_ARRAY_INDEX, | 402 STRING_INDEX_IS_ARRAY_INDEX, |
| (...skipping 2248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2657 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase); | 2651 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase); |
| 2658 | 2652 |
| 2659 // Index is not a smi. | 2653 // Index is not a smi. |
| 2660 __ bind(&index_not_smi_); | 2654 __ bind(&index_not_smi_); |
| 2661 // If index is a heap number, try converting it to an integer. | 2655 // If index is a heap number, try converting it to an integer. |
| 2662 __ CheckMap(index_, | 2656 __ CheckMap(index_, |
| 2663 masm->isolate()->factory()->heap_number_map(), | 2657 masm->isolate()->factory()->heap_number_map(), |
| 2664 index_not_number_, | 2658 index_not_number_, |
| 2665 DONT_DO_SMI_CHECK); | 2659 DONT_DO_SMI_CHECK); |
| 2666 call_helper.BeforeCall(masm); | 2660 call_helper.BeforeCall(masm); |
| 2667 if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) { | 2661 if (embed_mode == PART_OF_IC_HANDLER) { |
| 2668 __ push(VectorLoadICDescriptor::VectorRegister()); | 2662 __ push(VectorLoadICDescriptor::VectorRegister()); |
| 2669 __ push(VectorLoadICDescriptor::SlotRegister()); | 2663 __ push(VectorLoadICDescriptor::SlotRegister()); |
| 2670 } | 2664 } |
| 2671 __ push(object_); | 2665 __ push(object_); |
| 2672 __ push(index_); // Consumed by runtime conversion function. | 2666 __ push(index_); // Consumed by runtime conversion function. |
| 2673 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 2667 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
| 2674 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 2668 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
| 2675 } else { | 2669 } else { |
| 2676 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 2670 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
| 2677 // NumberToSmi discards numbers that are not exact integers. | 2671 // NumberToSmi discards numbers that are not exact integers. |
| 2678 __ CallRuntime(Runtime::kNumberToSmi, 1); | 2672 __ CallRuntime(Runtime::kNumberToSmi, 1); |
| 2679 } | 2673 } |
| 2680 if (!index_.is(eax)) { | 2674 if (!index_.is(eax)) { |
| 2681 // Save the conversion result before the pop instructions below | 2675 // Save the conversion result before the pop instructions below |
| 2682 // have a chance to overwrite it. | 2676 // have a chance to overwrite it. |
| 2683 __ mov(index_, eax); | 2677 __ mov(index_, eax); |
| 2684 } | 2678 } |
| 2685 __ pop(object_); | 2679 __ pop(object_); |
| 2686 if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) { | 2680 if (embed_mode == PART_OF_IC_HANDLER) { |
| 2687 __ pop(VectorLoadICDescriptor::SlotRegister()); | 2681 __ pop(VectorLoadICDescriptor::SlotRegister()); |
| 2688 __ pop(VectorLoadICDescriptor::VectorRegister()); | 2682 __ pop(VectorLoadICDescriptor::VectorRegister()); |
| 2689 } | 2683 } |
| 2690 // Reload the instance type. | 2684 // Reload the instance type. |
| 2691 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 2685 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
| 2692 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 2686 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
| 2693 call_helper.AfterCall(masm); | 2687 call_helper.AfterCall(masm); |
| 2694 // If index is still not a smi, it must be out of range. | 2688 // If index is still not a smi, it must be out of range. |
| 2695 STATIC_ASSERT(kSmiTag == 0); | 2689 STATIC_ASSERT(kSmiTag == 0); |
| 2696 __ JumpIfNotSmi(index_, index_out_of_range_); | 2690 __ JumpIfNotSmi(index_, index_out_of_range_); |
| (...skipping 2394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5091 ApiParameterOperand(2), kStackSpace, nullptr, | 5085 ApiParameterOperand(2), kStackSpace, nullptr, |
| 5092 Operand(ebp, 7 * kPointerSize), NULL); | 5086 Operand(ebp, 7 * kPointerSize), NULL); |
| 5093 } | 5087 } |
| 5094 | 5088 |
| 5095 | 5089 |
| 5096 #undef __ | 5090 #undef __ |
| 5097 | 5091 |
| 5098 } } // namespace v8::internal | 5092 } } // namespace v8::internal |
| 5099 | 5093 |
| 5100 #endif // V8_TARGET_ARCH_X87 | 5094 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |