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