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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 CODE_STUB_LIST(DEF_CASE) | 176 CODE_STUB_LIST(DEF_CASE) |
177 #undef DEF_CASE | 177 #undef DEF_CASE |
178 default: | 178 default: |
179 if (!allow_unknown_keys) { | 179 if (!allow_unknown_keys) { |
180 UNREACHABLE(); | 180 UNREACHABLE(); |
181 } | 181 } |
182 return NULL; | 182 return NULL; |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
| 186 void CodeStub::PrintBaseName(StringStream* stream) { |
| 187 stream->Add("%s", MajorName(MajorKey(), false)); |
| 188 } |
| 189 |
| 190 |
| 191 void CodeStub::PrintName(StringStream* stream) { |
| 192 PrintBaseName(stream); |
| 193 PrintState(stream); |
| 194 } |
| 195 |
| 196 |
| 197 Builtins::JavaScript UnaryOpStub::ToJSBuiltin() { |
| 198 switch (operation_) { |
| 199 default: |
| 200 UNREACHABLE(); |
| 201 case Token::SUB: |
| 202 return Builtins::UNARY_MINUS; |
| 203 case Token::BIT_NOT: |
| 204 return Builtins::BIT_NOT; |
| 205 } |
| 206 } |
| 207 |
186 | 208 |
187 void CodeStub::PrintName(StringStream* stream) { | 209 Handle<JSFunction> UnaryOpStub::ToJSFunction(Isolate* isolate) { |
188 stream->Add("%s", MajorName(MajorKey(), false)); | 210 Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object()); |
| 211 Object* builtin = builtins->javascript_builtin(ToJSBuiltin()); |
| 212 return Handle<JSFunction>(JSFunction::cast(builtin), isolate); |
189 } | 213 } |
190 | 214 |
191 | 215 |
| 216 MaybeObject* UnaryOpStub::Result(Handle<Object> object, Isolate* isolate) { |
| 217 Handle<JSFunction> builtin_function = ToJSFunction(isolate); |
| 218 bool caught_exception; |
| 219 Handle<Object> result = Execution::Call(builtin_function, object, |
| 220 0, NULL, &caught_exception); |
| 221 if (caught_exception) { |
| 222 return Failure::Exception(); |
| 223 } |
| 224 return *result; |
| 225 } |
| 226 |
| 227 |
| 228 void UnaryOpStub::UpdateStatus(Handle<Object> object) { |
| 229 State old_state(state_); |
| 230 if (object->IsSmi()) { |
| 231 state_.Add(SMI); |
| 232 if (operation_ == Token::SUB && *object == 0) { |
| 233 // The result (-0) has to be represented as double. |
| 234 state_.Add(HEAP_NUMBER); |
| 235 } |
| 236 } else if (object->IsHeapNumber()) { |
| 237 state_.Add(HEAP_NUMBER); |
| 238 } else { |
| 239 state_.Add(GENERIC); |
| 240 } |
| 241 TraceTransition(old_state, state_); |
| 242 } |
| 243 |
| 244 |
| 245 Handle<Type> UnaryOpStub::GetType(Isolate* isolate) { |
| 246 if (state_.Contains(GENERIC)) { |
| 247 return handle(Type::Any(), isolate); |
| 248 } |
| 249 Handle<Type> type = handle(Type::None(), isolate); |
| 250 if (state_.Contains(SMI)) { |
| 251 type = handle( |
| 252 Type::Union(type, handle(Type::Smi(), isolate)), isolate); |
| 253 } |
| 254 if (state_.Contains(HEAP_NUMBER)) { |
| 255 type = handle( |
| 256 Type::Union(type, handle(Type::Double(), isolate)), isolate); |
| 257 } |
| 258 return type; |
| 259 } |
| 260 |
| 261 |
192 void BinaryOpStub::Generate(MacroAssembler* masm) { | 262 void BinaryOpStub::Generate(MacroAssembler* masm) { |
193 // Explicitly allow generation of nested stubs. It is safe here because | 263 // Explicitly allow generation of nested stubs. It is safe here because |
194 // generation code does not use any raw pointers. | 264 // generation code does not use any raw pointers. |
195 AllowStubCallsScope allow_stub_calls(masm, true); | 265 AllowStubCallsScope allow_stub_calls(masm, true); |
196 | 266 |
197 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_); | 267 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_); |
198 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) { | 268 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) { |
199 // The OddballStub handles a number and an oddball, not two oddballs. | 269 // The OddballStub handles a number and an oddball, not two oddballs. |
200 operands_type = BinaryOpIC::GENERIC; | 270 operands_type = BinaryOpIC::GENERIC; |
201 } | 271 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 break; | 337 break; |
268 default: | 338 default: |
269 UNREACHABLE(); | 339 UNREACHABLE(); |
270 } | 340 } |
271 } | 341 } |
272 | 342 |
273 | 343 |
274 #undef __ | 344 #undef __ |
275 | 345 |
276 | 346 |
| 347 void UnaryOpStub::PrintBaseName(StringStream* stream) { |
| 348 CodeStub::PrintBaseName(stream); |
| 349 if (operation_ == Token::SUB) stream->Add("Minus"); |
| 350 if (operation_ == Token::BIT_NOT) stream->Add("Not"); |
| 351 } |
| 352 |
| 353 |
| 354 void UnaryOpStub::PrintState(StringStream* stream) { |
| 355 state_.Print(stream); |
| 356 } |
| 357 |
| 358 |
| 359 void UnaryOpStub::State::Print(StringStream* stream) const { |
| 360 stream->Add("("); |
| 361 SimpleListPrinter printer(stream); |
| 362 if (IsEmpty()) printer.Add("None"); |
| 363 if (Contains(GENERIC)) printer.Add("Generic"); |
| 364 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); |
| 365 if (Contains(SMI)) printer.Add("Smi"); |
| 366 stream->Add(")"); |
| 367 } |
| 368 |
| 369 |
277 void BinaryOpStub::PrintName(StringStream* stream) { | 370 void BinaryOpStub::PrintName(StringStream* stream) { |
278 const char* op_name = Token::Name(op_); | 371 const char* op_name = Token::Name(op_); |
279 const char* overwrite_name; | 372 const char* overwrite_name; |
280 switch (mode_) { | 373 switch (mode_) { |
281 case NO_OVERWRITE: overwrite_name = "Alloc"; break; | 374 case NO_OVERWRITE: overwrite_name = "Alloc"; break; |
282 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; | 375 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; |
283 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; | 376 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; |
284 default: overwrite_name = "UnknownOverwrite"; break; | 377 default: overwrite_name = "UnknownOverwrite"; break; |
285 } | 378 } |
286 stream->Add("BinaryOpStub_%s_%s_%s+%s", | 379 stream->Add("BinaryOpStub_%s_%s_%s+%s", |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 ASSERT(*known_map_ != NULL); | 516 ASSERT(*known_map_ != NULL); |
424 GenerateKnownObjects(masm); | 517 GenerateKnownObjects(masm); |
425 break; | 518 break; |
426 case CompareIC::GENERIC: | 519 case CompareIC::GENERIC: |
427 GenerateGeneric(masm); | 520 GenerateGeneric(masm); |
428 break; | 521 break; |
429 } | 522 } |
430 } | 523 } |
431 | 524 |
432 | 525 |
433 void CompareNilICStub::Record(Handle<Object> object) { | 526 void CompareNilICStub::UpdateStatus(Handle<Object> object) { |
434 ASSERT(state_ != State::Generic()); | 527 ASSERT(state_ != State::Generic()); |
| 528 State old_state(state_); |
435 if (object->IsNull()) { | 529 if (object->IsNull()) { |
436 state_.Add(NULL_TYPE); | 530 state_.Add(NULL_TYPE); |
437 } else if (object->IsUndefined()) { | 531 } else if (object->IsUndefined()) { |
438 state_.Add(UNDEFINED); | 532 state_.Add(UNDEFINED); |
439 } else if (object->IsUndetectableObject() || | 533 } else if (object->IsUndetectableObject() || |
440 object->IsOddball() || | 534 object->IsOddball() || |
441 !object->IsHeapObject()) { | 535 !object->IsHeapObject()) { |
442 state_ = State::Generic(); | 536 state_ = State::Generic(); |
443 } else if (IsMonomorphic()) { | 537 } else if (IsMonomorphic()) { |
444 state_ = State::Generic(); | 538 state_ = State::Generic(); |
445 } else { | 539 } else { |
446 state_.Add(MONOMORPHIC_MAP); | 540 state_.Add(MONOMORPHIC_MAP); |
447 } | 541 } |
| 542 TraceTransition(old_state, state_); |
448 } | 543 } |
449 | 544 |
450 | 545 |
451 void CompareNilICStub::State::TraceTransition(State to) const { | 546 template<class StateType> |
| 547 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { |
452 #ifdef DEBUG | 548 #ifdef DEBUG |
453 if (!FLAG_trace_ic) return; | 549 if (!FLAG_trace_ic) return; |
454 char buffer[100]; | 550 char buffer[100]; |
455 NoAllocationStringAllocator allocator(buffer, | 551 NoAllocationStringAllocator allocator(buffer, |
456 static_cast<unsigned>(sizeof(buffer))); | 552 static_cast<unsigned>(sizeof(buffer))); |
457 StringStream stream(&allocator); | 553 StringStream stream(&allocator); |
458 stream.Add("[CompareNilIC : "); | 554 stream.Add("["); |
459 Print(&stream); | 555 PrintBaseName(&stream); |
| 556 stream.Add(": "); |
| 557 from.Print(&stream); |
460 stream.Add("=>"); | 558 stream.Add("=>"); |
461 to.Print(&stream); | 559 to.Print(&stream); |
462 stream.Add("]\n"); | 560 stream.Add("]\n"); |
463 stream.OutputToStdOut(); | 561 stream.OutputToStdOut(); |
464 #endif | 562 #endif |
465 } | 563 } |
466 | 564 |
| 565 void CompareNilICStub::PrintBaseName(StringStream* stream) { |
| 566 CodeStub::PrintBaseName(stream); |
| 567 stream->Add((nil_value_ == kNullValue) ? "(NullValue)": |
| 568 "(UndefinedValue)"); |
| 569 } |
467 | 570 |
468 void CompareNilICStub::PrintName(StringStream* stream) { | 571 void CompareNilICStub::PrintState(StringStream* stream) { |
469 stream->Add("CompareNilICStub_"); | |
470 state_.Print(stream); | 572 state_.Print(stream); |
471 stream->Add((nil_value_ == kNullValue) ? "(NullValue|": | |
472 "(UndefinedValue|"); | |
473 } | 573 } |
474 | 574 |
475 | 575 |
476 void CompareNilICStub::State::Print(StringStream* stream) const { | 576 void CompareNilICStub::State::Print(StringStream* stream) const { |
477 stream->Add("("); | 577 stream->Add("("); |
478 SimpleListPrinter printer(stream); | 578 SimpleListPrinter printer(stream); |
479 if (IsEmpty()) printer.Add("None"); | 579 if (IsEmpty()) printer.Add("None"); |
480 if (Contains(UNDEFINED)) printer.Add("Undefined"); | 580 if (Contains(UNDEFINED)) printer.Add("Undefined"); |
481 if (Contains(NULL_TYPE)) printer.Add("Null"); | 581 if (Contains(NULL_TYPE)) printer.Add("Null"); |
482 if (Contains(MONOMORPHIC_MAP)) printer.Add("MonomorphicMap"); | 582 if (Contains(MONOMORPHIC_MAP)) printer.Add("MonomorphicMap"); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 if (RecordCallTarget()) stream->Add("_Recording"); | 707 if (RecordCallTarget()) stream->Add("_Recording"); |
608 } | 708 } |
609 | 709 |
610 | 710 |
611 void CallConstructStub::PrintName(StringStream* stream) { | 711 void CallConstructStub::PrintName(StringStream* stream) { |
612 stream->Add("CallConstructStub"); | 712 stream->Add("CallConstructStub"); |
613 if (RecordCallTarget()) stream->Add("_Recording"); | 713 if (RecordCallTarget()) stream->Add("_Recording"); |
614 } | 714 } |
615 | 715 |
616 | 716 |
617 bool ToBooleanStub::Record(Handle<Object> object) { | 717 bool ToBooleanStub::UpdateStatus(Handle<Object> object) { |
618 Types old_types(types_); | 718 Types old_types(types_); |
619 bool to_boolean_value = types_.Record(object); | 719 bool to_boolean_value = types_.UpdateStatus(object); |
620 old_types.TraceTransition(types_); | 720 TraceTransition(old_types, types_); |
621 return to_boolean_value; | 721 return to_boolean_value; |
622 } | 722 } |
623 | 723 |
624 | 724 |
625 void ToBooleanStub::PrintName(StringStream* stream) { | 725 void ToBooleanStub::PrintState(StringStream* stream) { |
626 stream->Add("ToBooleanStub_"); | |
627 types_.Print(stream); | 726 types_.Print(stream); |
628 } | 727 } |
629 | 728 |
630 | 729 |
631 void ToBooleanStub::Types::Print(StringStream* stream) const { | 730 void ToBooleanStub::Types::Print(StringStream* stream) const { |
632 stream->Add("("); | 731 stream->Add("("); |
633 SimpleListPrinter printer(stream); | 732 SimpleListPrinter printer(stream); |
634 if (IsEmpty()) printer.Add("None"); | 733 if (IsEmpty()) printer.Add("None"); |
635 if (Contains(UNDEFINED)) printer.Add("Undefined"); | 734 if (Contains(UNDEFINED)) printer.Add("Undefined"); |
636 if (Contains(BOOLEAN)) printer.Add("Bool"); | 735 if (Contains(BOOLEAN)) printer.Add("Bool"); |
637 if (Contains(NULL_TYPE)) printer.Add("Null"); | 736 if (Contains(NULL_TYPE)) printer.Add("Null"); |
638 if (Contains(SMI)) printer.Add("Smi"); | 737 if (Contains(SMI)) printer.Add("Smi"); |
639 if (Contains(SPEC_OBJECT)) printer.Add("SpecObject"); | 738 if (Contains(SPEC_OBJECT)) printer.Add("SpecObject"); |
640 if (Contains(STRING)) printer.Add("String"); | 739 if (Contains(STRING)) printer.Add("String"); |
641 if (Contains(SYMBOL)) printer.Add("Symbol"); | 740 if (Contains(SYMBOL)) printer.Add("Symbol"); |
642 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); | 741 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); |
643 stream->Add(")"); | 742 stream->Add(")"); |
644 } | 743 } |
645 | 744 |
646 | 745 |
647 void ToBooleanStub::Types::TraceTransition(Types to) const { | 746 bool ToBooleanStub::Types::UpdateStatus(Handle<Object> object) { |
648 #ifdef DEBUG | |
649 if (!FLAG_trace_ic) return; | |
650 char buffer[100]; | |
651 NoAllocationStringAllocator allocator(buffer, | |
652 static_cast<unsigned>(sizeof(buffer))); | |
653 StringStream stream(&allocator); | |
654 stream.Add("[ToBooleanIC : "); | |
655 Print(&stream); | |
656 stream.Add("=>"); | |
657 to.Print(&stream); | |
658 stream.Add("]\n"); | |
659 stream.OutputToStdOut(); | |
660 #endif | |
661 } | |
662 | |
663 | |
664 bool ToBooleanStub::Types::Record(Handle<Object> object) { | |
665 if (object->IsUndefined()) { | 747 if (object->IsUndefined()) { |
666 Add(UNDEFINED); | 748 Add(UNDEFINED); |
667 return false; | 749 return false; |
668 } else if (object->IsBoolean()) { | 750 } else if (object->IsBoolean()) { |
669 Add(BOOLEAN); | 751 Add(BOOLEAN); |
670 return object->IsTrue(); | 752 return object->IsTrue(); |
671 } else if (object->IsNull()) { | 753 } else if (object->IsNull()) { |
672 Add(NULL_TYPE); | 754 Add(NULL_TYPE); |
673 return false; | 755 return false; |
674 } else if (object->IsSmi()) { | 756 } else if (object->IsSmi()) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 InstallDescriptor(isolate, &stub3); | 897 InstallDescriptor(isolate, &stub3); |
816 } | 898 } |
817 | 899 |
818 InternalArrayConstructorStub::InternalArrayConstructorStub( | 900 InternalArrayConstructorStub::InternalArrayConstructorStub( |
819 Isolate* isolate) { | 901 Isolate* isolate) { |
820 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 902 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
821 } | 903 } |
822 | 904 |
823 | 905 |
824 } } // namespace v8::internal | 906 } } // namespace v8::internal |
OLD | NEW |