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) { | 187 |
| 188 void CodeStub::PrintName(StringStream* stream) { |
188 stream->Add("%s", MajorName(MajorKey(), false)); | 189 stream->Add("%s", MajorName(MajorKey(), false)); |
189 } | 190 } |
190 | 191 |
191 | 192 |
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 | |
209 | |
210 Handle<JSFunction> UnaryOpStub::ToJSFunction(Isolate* isolate) { | |
211 Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object()); | |
212 Object* builtin = builtins->javascript_builtin(ToJSBuiltin()); | |
213 return Handle<JSFunction>(JSFunction::cast(builtin), isolate); | |
214 } | |
215 | |
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 | |
263 void BinaryOpStub::Generate(MacroAssembler* masm) { | 193 void BinaryOpStub::Generate(MacroAssembler* masm) { |
264 // Explicitly allow generation of nested stubs. It is safe here because | 194 // Explicitly allow generation of nested stubs. It is safe here because |
265 // generation code does not use any raw pointers. | 195 // generation code does not use any raw pointers. |
266 AllowStubCallsScope allow_stub_calls(masm, true); | 196 AllowStubCallsScope allow_stub_calls(masm, true); |
267 | 197 |
268 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_); | 198 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_); |
269 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) { | 199 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) { |
270 // The OddballStub handles a number and an oddball, not two oddballs. | 200 // The OddballStub handles a number and an oddball, not two oddballs. |
271 operands_type = BinaryOpIC::GENERIC; | 201 operands_type = BinaryOpIC::GENERIC; |
272 } | 202 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 break; | 268 break; |
339 default: | 269 default: |
340 UNREACHABLE(); | 270 UNREACHABLE(); |
341 } | 271 } |
342 } | 272 } |
343 | 273 |
344 | 274 |
345 #undef __ | 275 #undef __ |
346 | 276 |
347 | 277 |
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 | |
371 void BinaryOpStub::PrintName(StringStream* stream) { | 278 void BinaryOpStub::PrintName(StringStream* stream) { |
372 const char* op_name = Token::Name(op_); | 279 const char* op_name = Token::Name(op_); |
373 const char* overwrite_name; | 280 const char* overwrite_name; |
374 switch (mode_) { | 281 switch (mode_) { |
375 case NO_OVERWRITE: overwrite_name = "Alloc"; break; | 282 case NO_OVERWRITE: overwrite_name = "Alloc"; break; |
376 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; | 283 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; |
377 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; | 284 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; |
378 default: overwrite_name = "UnknownOverwrite"; break; | 285 default: overwrite_name = "UnknownOverwrite"; break; |
379 } | 286 } |
380 stream->Add("BinaryOpStub_%s_%s_%s+%s", | 287 stream->Add("BinaryOpStub_%s_%s_%s+%s", |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 ASSERT(*known_map_ != NULL); | 424 ASSERT(*known_map_ != NULL); |
518 GenerateKnownObjects(masm); | 425 GenerateKnownObjects(masm); |
519 break; | 426 break; |
520 case CompareIC::GENERIC: | 427 case CompareIC::GENERIC: |
521 GenerateGeneric(masm); | 428 GenerateGeneric(masm); |
522 break; | 429 break; |
523 } | 430 } |
524 } | 431 } |
525 | 432 |
526 | 433 |
527 void CompareNilICStub::UpdateStatus(Handle<Object> object) { | 434 void CompareNilICStub::Record(Handle<Object> object) { |
528 ASSERT(state_ != State::Generic()); | 435 ASSERT(state_ != State::Generic()); |
529 State old_state(state_); | |
530 if (object->IsNull()) { | 436 if (object->IsNull()) { |
531 state_.Add(NULL_TYPE); | 437 state_.Add(NULL_TYPE); |
532 } else if (object->IsUndefined()) { | 438 } else if (object->IsUndefined()) { |
533 state_.Add(UNDEFINED); | 439 state_.Add(UNDEFINED); |
534 } else if (object->IsUndetectableObject() || | 440 } else if (object->IsUndetectableObject() || |
535 object->IsOddball() || | 441 object->IsOddball() || |
536 !object->IsHeapObject()) { | 442 !object->IsHeapObject()) { |
537 state_ = State::Generic(); | 443 state_ = State::Generic(); |
538 } else if (IsMonomorphic()) { | 444 } else if (IsMonomorphic()) { |
539 state_ = State::Generic(); | 445 state_ = State::Generic(); |
540 } else { | 446 } else { |
541 state_.Add(MONOMORPHIC_MAP); | 447 state_.Add(MONOMORPHIC_MAP); |
542 } | 448 } |
543 TraceTransition(old_state, state_); | |
544 } | 449 } |
545 | 450 |
546 | 451 |
547 template<class StateType> | 452 void CompareNilICStub::State::TraceTransition(State to) const { |
548 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { | |
549 #ifdef DEBUG | 453 #ifdef DEBUG |
550 if (!FLAG_trace_ic) return; | 454 if (!FLAG_trace_ic) return; |
551 char buffer[100]; | 455 char buffer[100]; |
552 NoAllocationStringAllocator allocator(buffer, | 456 NoAllocationStringAllocator allocator(buffer, |
553 static_cast<unsigned>(sizeof(buffer))); | 457 static_cast<unsigned>(sizeof(buffer))); |
554 StringStream stream(&allocator); | 458 StringStream stream(&allocator); |
555 stream.Add("["); | 459 stream.Add("[CompareNilIC : "); |
556 PrintBaseName(&stream); | 460 Print(&stream); |
557 stream.Add(": "); | |
558 from.Print(&stream); | |
559 stream.Add("=>"); | 461 stream.Add("=>"); |
560 to.Print(&stream); | 462 to.Print(&stream); |
561 stream.Add("]\n"); | 463 stream.Add("]\n"); |
562 stream.OutputToStdOut(); | 464 stream.OutputToStdOut(); |
563 #endif | 465 #endif |
564 } | 466 } |
565 | 467 |
566 void CompareNilICStub::PrintBaseName(StringStream* stream) { | |
567 CodeStub::PrintBaseName(stream); | |
568 stream->Add((nil_value_ == kNullValue) ? "(NullValue)": | |
569 "(UndefinedValue)"); | |
570 } | |
571 | 468 |
572 void CompareNilICStub::PrintState(StringStream* stream) { | 469 void CompareNilICStub::PrintName(StringStream* stream) { |
| 470 stream->Add("CompareNilICStub_"); |
573 state_.Print(stream); | 471 state_.Print(stream); |
| 472 stream->Add((nil_value_ == kNullValue) ? "(NullValue|": |
| 473 "(UndefinedValue|"); |
574 } | 474 } |
575 | 475 |
576 | 476 |
577 void CompareNilICStub::State::Print(StringStream* stream) const { | 477 void CompareNilICStub::State::Print(StringStream* stream) const { |
578 stream->Add("("); | 478 stream->Add("("); |
579 SimpleListPrinter printer(stream); | 479 SimpleListPrinter printer(stream); |
580 if (IsEmpty()) printer.Add("None"); | 480 if (IsEmpty()) printer.Add("None"); |
581 if (Contains(UNDEFINED)) printer.Add("Undefined"); | 481 if (Contains(UNDEFINED)) printer.Add("Undefined"); |
582 if (Contains(NULL_TYPE)) printer.Add("Null"); | 482 if (Contains(NULL_TYPE)) printer.Add("Null"); |
583 if (Contains(MONOMORPHIC_MAP)) printer.Add("MonomorphicMap"); | 483 if (Contains(MONOMORPHIC_MAP)) printer.Add("MonomorphicMap"); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 if (RecordCallTarget()) stream->Add("_Recording"); | 608 if (RecordCallTarget()) stream->Add("_Recording"); |
709 } | 609 } |
710 | 610 |
711 | 611 |
712 void CallConstructStub::PrintName(StringStream* stream) { | 612 void CallConstructStub::PrintName(StringStream* stream) { |
713 stream->Add("CallConstructStub"); | 613 stream->Add("CallConstructStub"); |
714 if (RecordCallTarget()) stream->Add("_Recording"); | 614 if (RecordCallTarget()) stream->Add("_Recording"); |
715 } | 615 } |
716 | 616 |
717 | 617 |
718 bool ToBooleanStub::UpdateStatus(Handle<Object> object) { | 618 bool ToBooleanStub::Record(Handle<Object> object) { |
719 Types old_types(types_); | 619 Types old_types(types_); |
720 bool to_boolean_value = types_.UpdateStatus(object); | 620 bool to_boolean_value = types_.Record(object); |
721 TraceTransition(old_types, types_); | 621 old_types.TraceTransition(types_); |
722 return to_boolean_value; | 622 return to_boolean_value; |
723 } | 623 } |
724 | 624 |
725 | 625 |
726 void ToBooleanStub::PrintState(StringStream* stream) { | 626 void ToBooleanStub::PrintName(StringStream* stream) { |
| 627 stream->Add("ToBooleanStub_"); |
727 types_.Print(stream); | 628 types_.Print(stream); |
728 } | 629 } |
729 | 630 |
730 | 631 |
731 void ToBooleanStub::Types::Print(StringStream* stream) const { | 632 void ToBooleanStub::Types::Print(StringStream* stream) const { |
732 stream->Add("("); | 633 stream->Add("("); |
733 SimpleListPrinter printer(stream); | 634 SimpleListPrinter printer(stream); |
734 if (IsEmpty()) printer.Add("None"); | 635 if (IsEmpty()) printer.Add("None"); |
735 if (Contains(UNDEFINED)) printer.Add("Undefined"); | 636 if (Contains(UNDEFINED)) printer.Add("Undefined"); |
736 if (Contains(BOOLEAN)) printer.Add("Bool"); | 637 if (Contains(BOOLEAN)) printer.Add("Bool"); |
737 if (Contains(NULL_TYPE)) printer.Add("Null"); | 638 if (Contains(NULL_TYPE)) printer.Add("Null"); |
738 if (Contains(SMI)) printer.Add("Smi"); | 639 if (Contains(SMI)) printer.Add("Smi"); |
739 if (Contains(SPEC_OBJECT)) printer.Add("SpecObject"); | 640 if (Contains(SPEC_OBJECT)) printer.Add("SpecObject"); |
740 if (Contains(STRING)) printer.Add("String"); | 641 if (Contains(STRING)) printer.Add("String"); |
741 if (Contains(SYMBOL)) printer.Add("Symbol"); | 642 if (Contains(SYMBOL)) printer.Add("Symbol"); |
742 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); | 643 if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); |
743 stream->Add(")"); | 644 stream->Add(")"); |
744 } | 645 } |
745 | 646 |
746 | 647 |
747 bool ToBooleanStub::Types::UpdateStatus(Handle<Object> object) { | 648 void ToBooleanStub::Types::TraceTransition(Types to) const { |
| 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) { |
748 if (object->IsUndefined()) { | 666 if (object->IsUndefined()) { |
749 Add(UNDEFINED); | 667 Add(UNDEFINED); |
750 return false; | 668 return false; |
751 } else if (object->IsBoolean()) { | 669 } else if (object->IsBoolean()) { |
752 Add(BOOLEAN); | 670 Add(BOOLEAN); |
753 return object->IsTrue(); | 671 return object->IsTrue(); |
754 } else if (object->IsNull()) { | 672 } else if (object->IsNull()) { |
755 Add(NULL_TYPE); | 673 Add(NULL_TYPE); |
756 return false; | 674 return false; |
757 } else if (object->IsSmi()) { | 675 } else if (object->IsSmi()) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 InstallDescriptor(isolate, &stub3); | 816 InstallDescriptor(isolate, &stub3); |
899 } | 817 } |
900 | 818 |
901 InternalArrayConstructorStub::InternalArrayConstructorStub( | 819 InternalArrayConstructorStub::InternalArrayConstructorStub( |
902 Isolate* isolate) { | 820 Isolate* isolate) { |
903 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 821 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
904 } | 822 } |
905 | 823 |
906 | 824 |
907 } } // namespace v8::internal | 825 } } // namespace v8::internal |
OLD | NEW |