| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 __ j(greater, &negative, Label::kNear); | 504 __ j(greater, &negative, Label::kNear); |
| 505 __ mov(ecx, scratch2); | 505 __ mov(ecx, scratch2); |
| 506 __ jmp(&done, Label::kNear); | 506 __ jmp(&done, Label::kNear); |
| 507 __ bind(&negative); | 507 __ bind(&negative); |
| 508 __ sub(ecx, Operand(scratch2)); | 508 __ sub(ecx, Operand(scratch2)); |
| 509 __ bind(&done); | 509 __ bind(&done); |
| 510 } | 510 } |
| 511 } | 511 } |
| 512 | 512 |
| 513 | 513 |
| 514 const char* UnaryOpStub::GetName() { | 514 void UnaryOpStub::PrintName(StringStream* stream) { |
| 515 if (name_ != NULL) return name_; | |
| 516 const int kMaxNameLength = 100; | |
| 517 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 518 kMaxNameLength); | |
| 519 if (name_ == NULL) return "OOM"; | |
| 520 const char* op_name = Token::Name(op_); | 515 const char* op_name = Token::Name(op_); |
| 521 const char* overwrite_name = NULL; // Make g++ happy. | 516 const char* overwrite_name = NULL; // Make g++ happy. |
| 522 switch (mode_) { | 517 switch (mode_) { |
| 523 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; | 518 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; |
| 524 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; | 519 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; |
| 525 } | 520 } |
| 526 | 521 stream->Add("UnaryOpStub_%s_%s_%s", |
| 527 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | 522 op_name, |
| 528 "UnaryOpStub_%s_%s_%s", | 523 overwrite_name, |
| 529 op_name, | 524 UnaryOpIC::GetName(operand_type_)); |
| 530 overwrite_name, | |
| 531 UnaryOpIC::GetName(operand_type_)); | |
| 532 return name_; | |
| 533 } | 525 } |
| 534 | 526 |
| 535 | 527 |
| 536 // TODO(svenpanne): Use virtual functions instead of switch. | 528 // TODO(svenpanne): Use virtual functions instead of switch. |
| 537 void UnaryOpStub::Generate(MacroAssembler* masm) { | 529 void UnaryOpStub::Generate(MacroAssembler* masm) { |
| 538 switch (operand_type_) { | 530 switch (operand_type_) { |
| 539 case UnaryOpIC::UNINITIALIZED: | 531 case UnaryOpIC::UNINITIALIZED: |
| 540 GenerateTypeTransition(masm); | 532 GenerateTypeTransition(masm); |
| 541 break; | 533 break; |
| 542 case UnaryOpIC::SMI: | 534 case UnaryOpIC::SMI: |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 break; | 899 break; |
| 908 case BinaryOpIC::GENERIC: | 900 case BinaryOpIC::GENERIC: |
| 909 GenerateGeneric(masm); | 901 GenerateGeneric(masm); |
| 910 break; | 902 break; |
| 911 default: | 903 default: |
| 912 UNREACHABLE(); | 904 UNREACHABLE(); |
| 913 } | 905 } |
| 914 } | 906 } |
| 915 | 907 |
| 916 | 908 |
| 917 const char* BinaryOpStub::GetName() { | 909 void BinaryOpStub::PrintName(StringStream* stream) { |
| 918 if (name_ != NULL) return name_; | |
| 919 const int kMaxNameLength = 100; | |
| 920 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 921 kMaxNameLength); | |
| 922 if (name_ == NULL) return "OOM"; | |
| 923 const char* op_name = Token::Name(op_); | 910 const char* op_name = Token::Name(op_); |
| 924 const char* overwrite_name; | 911 const char* overwrite_name; |
| 925 switch (mode_) { | 912 switch (mode_) { |
| 926 case NO_OVERWRITE: overwrite_name = "Alloc"; break; | 913 case NO_OVERWRITE: overwrite_name = "Alloc"; break; |
| 927 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; | 914 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; |
| 928 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; | 915 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; |
| 929 default: overwrite_name = "UnknownOverwrite"; break; | 916 default: overwrite_name = "UnknownOverwrite"; break; |
| 930 } | 917 } |
| 931 | 918 stream->Add("BinaryOpStub_%s_%s_%s", |
| 932 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | 919 op_name, |
| 933 "BinaryOpStub_%s_%s_%s", | 920 overwrite_name, |
| 934 op_name, | 921 BinaryOpIC::GetName(operands_type_)); |
| 935 overwrite_name, | |
| 936 BinaryOpIC::GetName(operands_type_)); | |
| 937 return name_; | |
| 938 } | 922 } |
| 939 | 923 |
| 940 | 924 |
| 941 void BinaryOpStub::GenerateSmiCode( | 925 void BinaryOpStub::GenerateSmiCode( |
| 942 MacroAssembler* masm, | 926 MacroAssembler* masm, |
| 943 Label* slow, | 927 Label* slow, |
| 944 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { | 928 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { |
| 945 // 1. Move arguments into edx, eax except for DIV and MOD, which need the | 929 // 1. Move arguments into edx, eax except for DIV and MOD, which need the |
| 946 // dividend in eax and edx free for the division. Use eax, ebx for those. | 930 // dividend in eax and edx free for the division. Use eax, ebx for those. |
| 947 Comment load_comment(masm, "-- Load arguments"); | 931 Comment load_comment(masm, "-- Load arguments"); |
| (...skipping 3425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4373 __ bind(&throw_termination_exception); | 4357 __ bind(&throw_termination_exception); |
| 4374 GenerateThrowUncatchable(masm, TERMINATION); | 4358 GenerateThrowUncatchable(masm, TERMINATION); |
| 4375 | 4359 |
| 4376 __ bind(&throw_normal_exception); | 4360 __ bind(&throw_normal_exception); |
| 4377 GenerateThrowTOS(masm); | 4361 GenerateThrowTOS(masm); |
| 4378 } | 4362 } |
| 4379 | 4363 |
| 4380 | 4364 |
| 4381 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { | 4365 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { |
| 4382 Label invoke, exit; | 4366 Label invoke, exit; |
| 4383 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 4384 Label not_outermost_js, not_outermost_js_2; | 4367 Label not_outermost_js, not_outermost_js_2; |
| 4385 #endif | |
| 4386 | 4368 |
| 4387 // Setup frame. | 4369 // Setup frame. |
| 4388 __ push(ebp); | 4370 __ push(ebp); |
| 4389 __ mov(ebp, Operand(esp)); | 4371 __ mov(ebp, Operand(esp)); |
| 4390 | 4372 |
| 4391 // Push marker in two places. | 4373 // Push marker in two places. |
| 4392 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; | 4374 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
| 4393 __ push(Immediate(Smi::FromInt(marker))); // context slot | 4375 __ push(Immediate(Smi::FromInt(marker))); // context slot |
| 4394 __ push(Immediate(Smi::FromInt(marker))); // function slot | 4376 __ push(Immediate(Smi::FromInt(marker))); // function slot |
| 4395 // Save callee-saved registers (C calling conventions). | 4377 // Save callee-saved registers (C calling conventions). |
| 4396 __ push(edi); | 4378 __ push(edi); |
| 4397 __ push(esi); | 4379 __ push(esi); |
| 4398 __ push(ebx); | 4380 __ push(ebx); |
| 4399 | 4381 |
| 4400 // Save copies of the top frame descriptor on the stack. | 4382 // Save copies of the top frame descriptor on the stack. |
| 4401 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate()); | 4383 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate()); |
| 4402 __ push(Operand::StaticVariable(c_entry_fp)); | 4384 __ push(Operand::StaticVariable(c_entry_fp)); |
| 4403 | 4385 |
| 4404 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 4405 // If this is the outermost JS call, set js_entry_sp value. | 4386 // If this is the outermost JS call, set js_entry_sp value. |
| 4406 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, | 4387 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, |
| 4407 masm->isolate()); | 4388 masm->isolate()); |
| 4408 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); | 4389 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); |
| 4409 __ j(not_equal, ¬_outermost_js); | 4390 __ j(not_equal, ¬_outermost_js); |
| 4410 __ mov(Operand::StaticVariable(js_entry_sp), ebp); | 4391 __ mov(Operand::StaticVariable(js_entry_sp), ebp); |
| 4411 __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 4392 __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
| 4412 Label cont; | 4393 Label cont; |
| 4413 __ jmp(&cont); | 4394 __ jmp(&cont); |
| 4414 __ bind(¬_outermost_js); | 4395 __ bind(¬_outermost_js); |
| 4415 __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); | 4396 __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); |
| 4416 __ bind(&cont); | 4397 __ bind(&cont); |
| 4417 #endif | |
| 4418 | 4398 |
| 4419 // Call a faked try-block that does the invoke. | 4399 // Call a faked try-block that does the invoke. |
| 4420 __ call(&invoke); | 4400 __ call(&invoke); |
| 4421 | 4401 |
| 4422 // Caught exception: Store result (exception) in the pending | 4402 // Caught exception: Store result (exception) in the pending |
| 4423 // exception field in the JSEnv and return a failure sentinel. | 4403 // exception field in the JSEnv and return a failure sentinel. |
| 4424 ExternalReference pending_exception(Isolate::k_pending_exception_address, | 4404 ExternalReference pending_exception(Isolate::k_pending_exception_address, |
| 4425 masm->isolate()); | 4405 masm->isolate()); |
| 4426 __ mov(Operand::StaticVariable(pending_exception), eax); | 4406 __ mov(Operand::StaticVariable(pending_exception), eax); |
| 4427 __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); | 4407 __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 4455 __ mov(edx, Immediate(entry)); | 4435 __ mov(edx, Immediate(entry)); |
| 4456 } | 4436 } |
| 4457 __ mov(edx, Operand(edx, 0)); // deref address | 4437 __ mov(edx, Operand(edx, 0)); // deref address |
| 4458 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); | 4438 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); |
| 4459 __ call(Operand(edx)); | 4439 __ call(Operand(edx)); |
| 4460 | 4440 |
| 4461 // Unlink this frame from the handler chain. | 4441 // Unlink this frame from the handler chain. |
| 4462 __ PopTryHandler(); | 4442 __ PopTryHandler(); |
| 4463 | 4443 |
| 4464 __ bind(&exit); | 4444 __ bind(&exit); |
| 4465 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 4466 // Check if the current stack frame is marked as the outermost JS frame. | 4445 // Check if the current stack frame is marked as the outermost JS frame. |
| 4467 __ pop(ebx); | 4446 __ pop(ebx); |
| 4468 __ cmp(Operand(ebx), | 4447 __ cmp(Operand(ebx), |
| 4469 Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 4448 Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
| 4470 __ j(not_equal, ¬_outermost_js_2); | 4449 __ j(not_equal, ¬_outermost_js_2); |
| 4471 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0)); | 4450 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0)); |
| 4472 __ bind(¬_outermost_js_2); | 4451 __ bind(¬_outermost_js_2); |
| 4473 #endif | |
| 4474 | 4452 |
| 4475 // Restore the top frame descriptor from the stack. | 4453 // Restore the top frame descriptor from the stack. |
| 4476 __ pop(Operand::StaticVariable(ExternalReference( | 4454 __ pop(Operand::StaticVariable(ExternalReference( |
| 4477 Isolate::k_c_entry_fp_address, | 4455 Isolate::k_c_entry_fp_address, |
| 4478 masm->isolate()))); | 4456 masm->isolate()))); |
| 4479 | 4457 |
| 4480 // Restore callee-saved registers (C calling conventions). | 4458 // Restore callee-saved registers (C calling conventions). |
| 4481 __ pop(ebx); | 4459 __ pop(ebx); |
| 4482 __ pop(esi); | 4460 __ pop(esi); |
| 4483 __ pop(edi); | 4461 __ pop(edi); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4725 | RegisterField::encode(false) // lhs_ and rhs_ are not used | 4703 | RegisterField::encode(false) // lhs_ and rhs_ are not used |
| 4726 | StrictField::encode(strict_) | 4704 | StrictField::encode(strict_) |
| 4727 | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false) | 4705 | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false) |
| 4728 | IncludeNumberCompareField::encode(include_number_compare_) | 4706 | IncludeNumberCompareField::encode(include_number_compare_) |
| 4729 | IncludeSmiCompareField::encode(include_smi_compare_); | 4707 | IncludeSmiCompareField::encode(include_smi_compare_); |
| 4730 } | 4708 } |
| 4731 | 4709 |
| 4732 | 4710 |
| 4733 // Unfortunately you have to run without snapshots to see most of these | 4711 // Unfortunately you have to run without snapshots to see most of these |
| 4734 // names in the profile since most compare stubs end up in the snapshot. | 4712 // names in the profile since most compare stubs end up in the snapshot. |
| 4735 const char* CompareStub::GetName() { | 4713 void CompareStub::PrintName(StringStream* stream) { |
| 4736 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); | 4714 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); |
| 4737 | |
| 4738 if (name_ != NULL) return name_; | |
| 4739 const int kMaxNameLength = 100; | |
| 4740 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 4741 kMaxNameLength); | |
| 4742 if (name_ == NULL) return "OOM"; | |
| 4743 | |
| 4744 const char* cc_name; | 4715 const char* cc_name; |
| 4745 switch (cc_) { | 4716 switch (cc_) { |
| 4746 case less: cc_name = "LT"; break; | 4717 case less: cc_name = "LT"; break; |
| 4747 case greater: cc_name = "GT"; break; | 4718 case greater: cc_name = "GT"; break; |
| 4748 case less_equal: cc_name = "LE"; break; | 4719 case less_equal: cc_name = "LE"; break; |
| 4749 case greater_equal: cc_name = "GE"; break; | 4720 case greater_equal: cc_name = "GE"; break; |
| 4750 case equal: cc_name = "EQ"; break; | 4721 case equal: cc_name = "EQ"; break; |
| 4751 case not_equal: cc_name = "NE"; break; | 4722 case not_equal: cc_name = "NE"; break; |
| 4752 default: cc_name = "UnknownCondition"; break; | 4723 default: cc_name = "UnknownCondition"; break; |
| 4753 } | 4724 } |
| 4754 | 4725 bool is_equality = cc_ == equal || cc_ == not_equal; |
| 4755 const char* strict_name = ""; | 4726 stream->Add("CompareStub_%s", cc_name); |
| 4756 if (strict_ && (cc_ == equal || cc_ == not_equal)) { | 4727 if (strict_ && is_equality) stream->Add("_STRICT"); |
| 4757 strict_name = "_STRICT"; | 4728 if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN"); |
| 4758 } | 4729 if (!include_number_compare_) stream->Add("_NO_NUMBER"); |
| 4759 | 4730 if (!include_smi_compare_) stream->Add("_NO_SMI"); |
| 4760 const char* never_nan_nan_name = ""; | |
| 4761 if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) { | |
| 4762 never_nan_nan_name = "_NO_NAN"; | |
| 4763 } | |
| 4764 | |
| 4765 const char* include_number_compare_name = ""; | |
| 4766 if (!include_number_compare_) { | |
| 4767 include_number_compare_name = "_NO_NUMBER"; | |
| 4768 } | |
| 4769 | |
| 4770 const char* include_smi_compare_name = ""; | |
| 4771 if (!include_smi_compare_) { | |
| 4772 include_smi_compare_name = "_NO_SMI"; | |
| 4773 } | |
| 4774 | |
| 4775 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | |
| 4776 "CompareStub_%s%s%s%s%s", | |
| 4777 cc_name, | |
| 4778 strict_name, | |
| 4779 never_nan_nan_name, | |
| 4780 include_number_compare_name, | |
| 4781 include_smi_compare_name); | |
| 4782 return name_; | |
| 4783 } | 4731 } |
| 4784 | 4732 |
| 4785 | 4733 |
| 4786 // ------------------------------------------------------------------------- | 4734 // ------------------------------------------------------------------------- |
| 4787 // StringCharCodeAtGenerator | 4735 // StringCharCodeAtGenerator |
| 4788 | 4736 |
| 4789 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 4737 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
| 4790 Label flat_string; | 4738 Label flat_string; |
| 4791 Label ascii_string; | 4739 Label ascii_string; |
| 4792 Label got_char_code; | 4740 Label got_char_code; |
| (...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6344 __ Drop(1); | 6292 __ Drop(1); |
| 6345 __ ret(2 * kPointerSize); | 6293 __ ret(2 * kPointerSize); |
| 6346 } | 6294 } |
| 6347 | 6295 |
| 6348 | 6296 |
| 6349 #undef __ | 6297 #undef __ |
| 6350 | 6298 |
| 6351 } } // namespace v8::internal | 6299 } } // namespace v8::internal |
| 6352 | 6300 |
| 6353 #endif // V8_TARGET_ARCH_IA32 | 6301 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |