| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 // Return the address in the original code. This is the place where | 131 // Return the address in the original code. This is the place where |
| 132 // the call which has been overwritten by the DebugBreakXXX resides | 132 // the call which has been overwritten by the DebugBreakXXX resides |
| 133 // and the place where the inline cache system should look. | 133 // and the place where the inline cache system should look. |
| 134 intptr_t delta = | 134 intptr_t delta = |
| 135 original_code->instruction_start() - code->instruction_start(); | 135 original_code->instruction_start() - code->instruction_start(); |
| 136 return addr + delta; | 136 return addr + delta; |
| 137 } | 137 } |
| 138 #endif | 138 #endif |
| 139 | 139 |
| 140 | 140 |
| 141 static bool HasNormalObjectsInPrototypeChain(LookupResult* lookup, | 141 static bool HasNormalObjectsInPrototypeChain(Isolate* isolate, |
| 142 LookupResult* lookup, |
| 142 Object* receiver) { | 143 Object* receiver) { |
| 143 Object* end = lookup->IsProperty() ? lookup->holder() : HEAP->null_value(); | 144 Object* end = lookup->IsProperty() |
| 145 ? lookup->holder() : isolate->heap()->null_value(); |
| 144 for (Object* current = receiver; | 146 for (Object* current = receiver; |
| 145 current != end; | 147 current != end; |
| 146 current = current->GetPrototype()) { | 148 current = current->GetPrototype()) { |
| 147 if (current->IsJSObject() && | 149 if (current->IsJSObject() && |
| 148 !JSObject::cast(current)->HasFastProperties() && | 150 !JSObject::cast(current)->HasFastProperties() && |
| 149 !current->IsJSGlobalProxy() && | 151 !current->IsJSGlobalProxy() && |
| 150 !current->IsJSGlobalObject()) { | 152 !current->IsJSGlobalObject()) { |
| 151 return true; | 153 return true; |
| 152 } | 154 } |
| 153 } | 155 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 if (receiver->IsJSBuiltinsObject()) { | 215 if (receiver->IsJSBuiltinsObject()) { |
| 214 return UNINITIALIZED; | 216 return UNINITIALIZED; |
| 215 } | 217 } |
| 216 | 218 |
| 217 return MONOMORPHIC; | 219 return MONOMORPHIC; |
| 218 } | 220 } |
| 219 | 221 |
| 220 | 222 |
| 221 RelocInfo::Mode IC::ComputeMode() { | 223 RelocInfo::Mode IC::ComputeMode() { |
| 222 Address addr = address(); | 224 Address addr = address(); |
| 223 Code* code = Code::cast(HEAP->FindCodeObject(addr)); | 225 Code* code = Code::cast(isolate()->heap()->FindCodeObject(addr)); |
| 224 for (RelocIterator it(code, RelocInfo::kCodeTargetMask); | 226 for (RelocIterator it(code, RelocInfo::kCodeTargetMask); |
| 225 !it.done(); it.next()) { | 227 !it.done(); it.next()) { |
| 226 RelocInfo* info = it.rinfo(); | 228 RelocInfo* info = it.rinfo(); |
| 227 if (info->pc() == addr) return info->rmode(); | 229 if (info->pc() == addr) return info->rmode(); |
| 228 } | 230 } |
| 229 UNREACHABLE(); | 231 UNREACHABLE(); |
| 230 return RelocInfo::NONE; | 232 return RelocInfo::NONE; |
| 231 } | 233 } |
| 232 | 234 |
| 233 | 235 |
| 234 Failure* IC::TypeError(const char* type, | 236 Failure* IC::TypeError(const char* type, |
| 235 Handle<Object> object, | 237 Handle<Object> object, |
| 236 Handle<Object> key) { | 238 Handle<Object> key) { |
| 237 HandleScope scope; | 239 HandleScope scope(isolate()); |
| 238 Handle<Object> args[2] = { key, object }; | 240 Handle<Object> args[2] = { key, object }; |
| 239 Handle<Object> error = FACTORY->NewTypeError(type, HandleVector(args, 2)); | 241 Handle<Object> error = isolate()->factory()->NewTypeError( |
| 242 type, HandleVector(args, 2)); |
| 240 return isolate()->Throw(*error); | 243 return isolate()->Throw(*error); |
| 241 } | 244 } |
| 242 | 245 |
| 243 | 246 |
| 244 Failure* IC::ReferenceError(const char* type, Handle<String> name) { | 247 Failure* IC::ReferenceError(const char* type, Handle<String> name) { |
| 245 HandleScope scope; | 248 HandleScope scope(isolate()); |
| 246 Handle<Object> error = | 249 Handle<Object> error = isolate()->factory()->NewReferenceError( |
| 247 FACTORY->NewReferenceError(type, HandleVector(&name, 1)); | 250 type, HandleVector(&name, 1)); |
| 248 return isolate()->Throw(*error); | 251 return isolate()->Throw(*error); |
| 249 } | 252 } |
| 250 | 253 |
| 251 | 254 |
| 252 void IC::Clear(Address address) { | 255 void IC::Clear(Address address) { |
| 253 Code* target = GetTargetAtAddress(address); | 256 Code* target = GetTargetAtAddress(address); |
| 254 | 257 |
| 255 // Don't clear debug break inline cache as it will remove the break point. | 258 // Don't clear debug break inline cache as it will remove the break point. |
| 256 if (target->ic_state() == DEBUG_BREAK) return; | 259 if (target->ic_state() == DEBUG_BREAK) return; |
| 257 | 260 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 lookup->NotFound(); | 460 lookup->NotFound(); |
| 458 return; | 461 return; |
| 459 } | 462 } |
| 460 | 463 |
| 461 object = proto; | 464 object = proto; |
| 462 } | 465 } |
| 463 } | 466 } |
| 464 | 467 |
| 465 | 468 |
| 466 Object* CallICBase::TryCallAsFunction(Object* object) { | 469 Object* CallICBase::TryCallAsFunction(Object* object) { |
| 467 HandleScope scope; | 470 HandleScope scope(isolate()); |
| 468 Handle<Object> target(object); | 471 Handle<Object> target(object, isolate()); |
| 469 Handle<Object> delegate = Execution::GetFunctionDelegate(target); | 472 Handle<Object> delegate = Execution::GetFunctionDelegate(target); |
| 470 | 473 |
| 471 if (delegate->IsJSFunction()) { | 474 if (delegate->IsJSFunction()) { |
| 472 // Patch the receiver and use the delegate as the function to | 475 // Patch the receiver and use the delegate as the function to |
| 473 // invoke. This is used for invoking objects as if they were | 476 // invoke. This is used for invoking objects as if they were |
| 474 // functions. | 477 // functions. |
| 475 const int argc = this->target()->arguments_count(); | 478 const int argc = this->target()->arguments_count(); |
| 476 StackFrameLocator locator; | 479 StackFrameLocator locator; |
| 477 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 480 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 478 int index = frame->ComputeExpressionsCount() - (argc + 1); | 481 int index = frame->ComputeExpressionsCount() - (argc + 1); |
| 479 frame->SetExpression(index, *target); | 482 frame->SetExpression(index, *target); |
| 480 } | 483 } |
| 481 | 484 |
| 482 return *delegate; | 485 return *delegate; |
| 483 } | 486 } |
| 484 | 487 |
| 485 | 488 |
| 486 void CallICBase::ReceiverToObject(Handle<Object> object) { | 489 void CallICBase::ReceiverToObject(Handle<Object> object) { |
| 487 HandleScope scope; | 490 HandleScope scope(isolate()); |
| 488 Handle<Object> receiver(object); | 491 Handle<Object> receiver = object; |
| 489 | 492 |
| 490 // Change the receiver to the result of calling ToObject on it. | 493 // Change the receiver to the result of calling ToObject on it. |
| 491 const int argc = this->target()->arguments_count(); | 494 const int argc = this->target()->arguments_count(); |
| 492 StackFrameLocator locator; | 495 StackFrameLocator locator; |
| 493 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 496 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 494 int index = frame->ComputeExpressionsCount() - (argc + 1); | 497 int index = frame->ComputeExpressionsCount() - (argc + 1); |
| 495 frame->SetExpression(index, *FACTORY->ToObject(object)); | 498 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); |
| 496 } | 499 } |
| 497 | 500 |
| 498 | 501 |
| 499 MaybeObject* CallICBase::LoadFunction(State state, | 502 MaybeObject* CallICBase::LoadFunction(State state, |
| 500 Handle<Object> object, | 503 Handle<Object> object, |
| 501 Handle<String> name) { | 504 Handle<String> name) { |
| 502 // If the object is undefined or null it's illegal to try to get any | 505 // If the object is undefined or null it's illegal to try to get any |
| 503 // of its properties; throw a TypeError in that case. | 506 // of its properties; throw a TypeError in that case. |
| 504 if (object->IsUndefined() || object->IsNull()) { | 507 if (object->IsUndefined() || object->IsNull()) { |
| 505 return TypeError("non_object_property_call", object, name); | 508 return TypeError("non_object_property_call", object, name); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 // If the object does not have the requested property, check which | 559 // If the object does not have the requested property, check which |
| 557 // exception we need to throw. | 560 // exception we need to throw. |
| 558 if (attr == ABSENT) { | 561 if (attr == ABSENT) { |
| 559 if (IsContextual(object)) { | 562 if (IsContextual(object)) { |
| 560 return ReferenceError("not_defined", name); | 563 return ReferenceError("not_defined", name); |
| 561 } | 564 } |
| 562 return TypeError("undefined_method", object, name); | 565 return TypeError("undefined_method", object, name); |
| 563 } | 566 } |
| 564 } | 567 } |
| 565 | 568 |
| 566 ASSERT(result != HEAP->the_hole_value()); | 569 ASSERT(result != isolate()->heap()->the_hole_value()); |
| 567 | 570 |
| 568 if (result->IsJSFunction()) { | 571 if (result->IsJSFunction()) { |
| 569 #ifdef ENABLE_DEBUGGER_SUPPORT | 572 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 570 // Handle stepping into a function if step into is active. | 573 // Handle stepping into a function if step into is active. |
| 571 Debug* debug = isolate()->debug(); | 574 Debug* debug = isolate()->debug(); |
| 572 if (debug->StepInActive()) { | 575 if (debug->StepInActive()) { |
| 573 // Protect the result in a handle as the debugger can allocate and might | 576 // Protect the result in a handle as the debugger can allocate and might |
| 574 // cause GC. | 577 // cause GC. |
| 575 HandleScope scope; | 578 HandleScope scope(isolate()); |
| 576 Handle<JSFunction> function(JSFunction::cast(result)); | 579 Handle<JSFunction> function(JSFunction::cast(result), isolate()); |
| 577 debug->HandleStepIn(function, object, fp(), false); | 580 debug->HandleStepIn(function, object, fp(), false); |
| 578 return *function; | 581 return *function; |
| 579 } | 582 } |
| 580 #endif | 583 #endif |
| 581 | 584 |
| 582 return result; | 585 return result; |
| 583 } | 586 } |
| 584 | 587 |
| 585 // Try to find a suitable function delegate for the object at hand. | 588 // Try to find a suitable function delegate for the object at hand. |
| 586 result = TryCallAsFunction(result); | 589 result = TryCallAsFunction(result); |
| 587 MaybeObject* answer = result; | 590 MaybeObject* answer = result; |
| 588 if (!result->IsJSFunction()) { | 591 if (!result->IsJSFunction()) { |
| 589 answer = TypeError("property_not_function", object, name); | 592 answer = TypeError("property_not_function", object, name); |
| 590 } | 593 } |
| 591 return answer; | 594 return answer; |
| 592 } | 595 } |
| 593 | 596 |
| 594 | 597 |
| 595 void CallICBase::UpdateCaches(LookupResult* lookup, | 598 void CallICBase::UpdateCaches(LookupResult* lookup, |
| 596 State state, | 599 State state, |
| 597 Handle<Object> object, | 600 Handle<Object> object, |
| 598 Handle<String> name) { | 601 Handle<String> name) { |
| 599 // Bail out if we didn't find a result. | 602 // Bail out if we didn't find a result. |
| 600 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; | 603 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; |
| 601 | 604 |
| 602 if (lookup->holder() != *object && | 605 if (lookup->holder() != *object && |
| 603 HasNormalObjectsInPrototypeChain(lookup, object->GetPrototype())) { | 606 HasNormalObjectsInPrototypeChain( |
| 607 isolate(), lookup, object->GetPrototype())) { |
| 604 // Suppress optimization for prototype chains with slow properties objects | 608 // Suppress optimization for prototype chains with slow properties objects |
| 605 // in the middle. | 609 // in the middle. |
| 606 return; | 610 return; |
| 607 } | 611 } |
| 608 | 612 |
| 609 // Compute the number of arguments. | 613 // Compute the number of arguments. |
| 610 int argc = target()->arguments_count(); | 614 int argc = target()->arguments_count(); |
| 611 InLoopFlag in_loop = target()->ic_in_loop(); | 615 InLoopFlag in_loop = target()->ic_in_loop(); |
| 612 MaybeObject* maybe_code = NULL; | 616 MaybeObject* maybe_code = NULL; |
| 613 Object* code; | 617 Object* code; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 if (object->IsUndefined() || object->IsNull()) { | 790 if (object->IsUndefined() || object->IsNull()) { |
| 787 return TypeError("non_object_property_load", object, name); | 791 return TypeError("non_object_property_load", object, name); |
| 788 } | 792 } |
| 789 | 793 |
| 790 if (FLAG_use_ic) { | 794 if (FLAG_use_ic) { |
| 791 // Use specialized code for getting the length of strings and | 795 // Use specialized code for getting the length of strings and |
| 792 // string wrapper objects. The length property of string wrapper | 796 // string wrapper objects. The length property of string wrapper |
| 793 // objects is read-only and therefore always returns the length of | 797 // objects is read-only and therefore always returns the length of |
| 794 // the underlying string value. See ECMA-262 15.5.5.1. | 798 // the underlying string value. See ECMA-262 15.5.5.1. |
| 795 if ((object->IsString() || object->IsStringWrapper()) && | 799 if ((object->IsString() || object->IsStringWrapper()) && |
| 796 name->Equals(HEAP->length_symbol())) { | 800 name->Equals(isolate()->heap()->length_symbol())) { |
| 797 HandleScope scope; | 801 HandleScope scope(isolate()); |
| 798 // Get the string if we have a string wrapper object. | 802 // Get the string if we have a string wrapper object. |
| 799 if (object->IsJSValue()) { | 803 if (object->IsJSValue()) { |
| 800 object = Handle<Object>(Handle<JSValue>::cast(object)->value()); | 804 object = Handle<Object>(Handle<JSValue>::cast(object)->value(), |
| 805 isolate()); |
| 801 } | 806 } |
| 802 #ifdef DEBUG | 807 #ifdef DEBUG |
| 803 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); | 808 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); |
| 804 #endif | 809 #endif |
| 805 Map* map = HeapObject::cast(*object)->map(); | 810 Map* map = HeapObject::cast(*object)->map(); |
| 806 if (object->IsString()) { | 811 if (object->IsString()) { |
| 807 const int offset = String::kLengthOffset; | 812 const int offset = String::kLengthOffset; |
| 808 PatchInlinedLoad(address(), map, offset); | 813 PatchInlinedLoad(address(), map, offset); |
| 809 } | 814 } |
| 810 | 815 |
| 811 Code* target = NULL; | 816 Code* target = NULL; |
| 812 target = isolate()->builtins()->builtin( | 817 target = isolate()->builtins()->builtin( |
| 813 Builtins::LoadIC_StringLength); | 818 Builtins::LoadIC_StringLength); |
| 814 set_target(target); | 819 set_target(target); |
| 815 return Smi::FromInt(String::cast(*object)->length()); | 820 return Smi::FromInt(String::cast(*object)->length()); |
| 816 } | 821 } |
| 817 | 822 |
| 818 // Use specialized code for getting the length of arrays. | 823 // Use specialized code for getting the length of arrays. |
| 819 if (object->IsJSArray() && name->Equals(HEAP->length_symbol())) { | 824 if (object->IsJSArray() && |
| 825 name->Equals(isolate()->heap()->length_symbol())) { |
| 820 #ifdef DEBUG | 826 #ifdef DEBUG |
| 821 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); | 827 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); |
| 822 #endif | 828 #endif |
| 823 Map* map = HeapObject::cast(*object)->map(); | 829 Map* map = HeapObject::cast(*object)->map(); |
| 824 const int offset = JSArray::kLengthOffset; | 830 const int offset = JSArray::kLengthOffset; |
| 825 PatchInlinedLoad(address(), map, offset); | 831 PatchInlinedLoad(address(), map, offset); |
| 826 | 832 |
| 827 Code* target = isolate()->builtins()->builtin( | 833 Code* target = isolate()->builtins()->builtin( |
| 828 Builtins::LoadIC_ArrayLength); | 834 Builtins::LoadIC_ArrayLength); |
| 829 set_target(target); | 835 set_target(target); |
| 830 return JSArray::cast(*object)->length(); | 836 return JSArray::cast(*object)->length(); |
| 831 } | 837 } |
| 832 | 838 |
| 833 // Use specialized code for getting prototype of functions. | 839 // Use specialized code for getting prototype of functions. |
| 834 if (object->IsJSFunction() && name->Equals(HEAP->prototype_symbol()) && | 840 if (object->IsJSFunction() && |
| 841 name->Equals(isolate()->heap()->prototype_symbol()) && |
| 835 JSFunction::cast(*object)->should_have_prototype()) { | 842 JSFunction::cast(*object)->should_have_prototype()) { |
| 836 #ifdef DEBUG | 843 #ifdef DEBUG |
| 837 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); | 844 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); |
| 838 #endif | 845 #endif |
| 839 Code* target = isolate()->builtins()->builtin( | 846 Code* target = isolate()->builtins()->builtin( |
| 840 Builtins::LoadIC_FunctionPrototype); | 847 Builtins::LoadIC_FunctionPrototype); |
| 841 set_target(target); | 848 set_target(target); |
| 842 return Accessors::FunctionGetPrototype(*object, 0); | 849 return Accessors::FunctionGetPrototype(*object, 0); |
| 843 } | 850 } |
| 844 } | 851 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 Handle<Object> object, | 955 Handle<Object> object, |
| 949 Handle<String> name) { | 956 Handle<String> name) { |
| 950 // Bail out if the result is not cacheable. | 957 // Bail out if the result is not cacheable. |
| 951 if (!lookup->IsCacheable()) return; | 958 if (!lookup->IsCacheable()) return; |
| 952 | 959 |
| 953 // Loading properties from values is not common, so don't try to | 960 // Loading properties from values is not common, so don't try to |
| 954 // deal with non-JS objects here. | 961 // deal with non-JS objects here. |
| 955 if (!object->IsJSObject()) return; | 962 if (!object->IsJSObject()) return; |
| 956 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 963 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 957 | 964 |
| 958 if (HasNormalObjectsInPrototypeChain(lookup, *object)) return; | 965 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return; |
| 959 | 966 |
| 960 // Compute the code stub for this load. | 967 // Compute the code stub for this load. |
| 961 MaybeObject* maybe_code = NULL; | 968 MaybeObject* maybe_code = NULL; |
| 962 Object* code; | 969 Object* code; |
| 963 if (state == UNINITIALIZED) { | 970 if (state == UNINITIALIZED) { |
| 964 // This is the first time we execute this inline cache. | 971 // This is the first time we execute this inline cache. |
| 965 // Set the target to the pre monomorphic stub to delay | 972 // Set the target to the pre monomorphic stub to delay |
| 966 // setting the monomorphic state. | 973 // setting the monomorphic state. |
| 967 maybe_code = pre_monomorphic_stub(); | 974 maybe_code = pre_monomorphic_stub(); |
| 968 } else if (!lookup->IsProperty()) { | 975 } else if (!lookup->IsProperty()) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 Handle<String> name = Handle<String>::cast(key); | 1065 Handle<String> name = Handle<String>::cast(key); |
| 1059 | 1066 |
| 1060 // If the object is undefined or null it's illegal to try to get any | 1067 // If the object is undefined or null it's illegal to try to get any |
| 1061 // of its properties; throw a TypeError in that case. | 1068 // of its properties; throw a TypeError in that case. |
| 1062 if (object->IsUndefined() || object->IsNull()) { | 1069 if (object->IsUndefined() || object->IsNull()) { |
| 1063 return TypeError("non_object_property_load", object, name); | 1070 return TypeError("non_object_property_load", object, name); |
| 1064 } | 1071 } |
| 1065 | 1072 |
| 1066 if (FLAG_use_ic) { | 1073 if (FLAG_use_ic) { |
| 1067 // Use specialized code for getting the length of strings. | 1074 // Use specialized code for getting the length of strings. |
| 1068 if (object->IsString() && name->Equals(HEAP->length_symbol())) { | 1075 if (object->IsString() && |
| 1076 name->Equals(isolate()->heap()->length_symbol())) { |
| 1069 Handle<String> string = Handle<String>::cast(object); | 1077 Handle<String> string = Handle<String>::cast(object); |
| 1070 Object* code = NULL; | 1078 Object* code = NULL; |
| 1071 { MaybeObject* maybe_code = | 1079 { MaybeObject* maybe_code = |
| 1072 isolate()->stub_cache()->ComputeKeyedLoadStringLength(*name, | 1080 isolate()->stub_cache()->ComputeKeyedLoadStringLength(*name, |
| 1073 *string); | 1081 *string); |
| 1074 if (!maybe_code->ToObject(&code)) return maybe_code; | 1082 if (!maybe_code->ToObject(&code)) return maybe_code; |
| 1075 } | 1083 } |
| 1076 set_target(Code::cast(code)); | 1084 set_target(Code::cast(code)); |
| 1077 #ifdef DEBUG | 1085 #ifdef DEBUG |
| 1078 TraceIC("KeyedLoadIC", name, state, target()); | 1086 TraceIC("KeyedLoadIC", name, state, target()); |
| 1079 #endif // DEBUG | 1087 #endif // DEBUG |
| 1080 return Smi::FromInt(string->length()); | 1088 return Smi::FromInt(string->length()); |
| 1081 } | 1089 } |
| 1082 | 1090 |
| 1083 // Use specialized code for getting the length of arrays. | 1091 // Use specialized code for getting the length of arrays. |
| 1084 if (object->IsJSArray() && name->Equals(HEAP->length_symbol())) { | 1092 if (object->IsJSArray() && |
| 1093 name->Equals(isolate()->heap()->length_symbol())) { |
| 1085 Handle<JSArray> array = Handle<JSArray>::cast(object); | 1094 Handle<JSArray> array = Handle<JSArray>::cast(object); |
| 1086 Object* code; | 1095 Object* code; |
| 1087 { MaybeObject* maybe_code = | 1096 { MaybeObject* maybe_code = |
| 1088 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(*name, | 1097 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(*name, |
| 1089 *array); | 1098 *array); |
| 1090 if (!maybe_code->ToObject(&code)) return maybe_code; | 1099 if (!maybe_code->ToObject(&code)) return maybe_code; |
| 1091 } | 1100 } |
| 1092 set_target(Code::cast(code)); | 1101 set_target(Code::cast(code)); |
| 1093 #ifdef DEBUG | 1102 #ifdef DEBUG |
| 1094 TraceIC("KeyedLoadIC", name, state, target()); | 1103 TraceIC("KeyedLoadIC", name, state, target()); |
| 1095 #endif // DEBUG | 1104 #endif // DEBUG |
| 1096 return JSArray::cast(*object)->length(); | 1105 return JSArray::cast(*object)->length(); |
| 1097 } | 1106 } |
| 1098 | 1107 |
| 1099 // Use specialized code for getting prototype of functions. | 1108 // Use specialized code for getting prototype of functions. |
| 1100 if (object->IsJSFunction() && name->Equals(HEAP->prototype_symbol()) && | 1109 if (object->IsJSFunction() && |
| 1110 name->Equals(isolate()->heap()->prototype_symbol()) && |
| 1101 JSFunction::cast(*object)->should_have_prototype()) { | 1111 JSFunction::cast(*object)->should_have_prototype()) { |
| 1102 Handle<JSFunction> function = Handle<JSFunction>::cast(object); | 1112 Handle<JSFunction> function = Handle<JSFunction>::cast(object); |
| 1103 Object* code; | 1113 Object* code; |
| 1104 { MaybeObject* maybe_code = | 1114 { MaybeObject* maybe_code = |
| 1105 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype( | 1115 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype( |
| 1106 *name, *function); | 1116 *name, *function); |
| 1107 if (!maybe_code->ToObject(&code)) return maybe_code; | 1117 if (!maybe_code->ToObject(&code)) return maybe_code; |
| 1108 } | 1118 } |
| 1109 set_target(Code::cast(code)); | 1119 set_target(Code::cast(code)); |
| 1110 #ifdef DEBUG | 1120 #ifdef DEBUG |
| 1111 TraceIC("KeyedLoadIC", name, state, target()); | 1121 TraceIC("KeyedLoadIC", name, state, target()); |
| 1112 #endif // DEBUG | 1122 #endif // DEBUG |
| 1113 return Accessors::FunctionGetPrototype(*object, 0); | 1123 return Accessors::FunctionGetPrototype(*object, 0); |
| 1114 } | 1124 } |
| 1115 } | 1125 } |
| 1116 | 1126 |
| 1117 // Check if the name is trivially convertible to an index and get | 1127 // Check if the name is trivially convertible to an index and get |
| 1118 // the element or char if so. | 1128 // the element or char if so. |
| 1119 uint32_t index = 0; | 1129 uint32_t index = 0; |
| 1120 if (name->AsArrayIndex(&index)) { | 1130 if (name->AsArrayIndex(&index)) { |
| 1121 HandleScope scope; | 1131 HandleScope scope(isolate()); |
| 1122 // Rewrite to the generic keyed load stub. | 1132 // Rewrite to the generic keyed load stub. |
| 1123 if (FLAG_use_ic) set_target(generic_stub()); | 1133 if (FLAG_use_ic) set_target(generic_stub()); |
| 1124 return Runtime::GetElementOrCharAt(isolate(), object, index); | 1134 return Runtime::GetElementOrCharAt(isolate(), object, index); |
| 1125 } | 1135 } |
| 1126 | 1136 |
| 1127 // Named lookup. | 1137 // Named lookup. |
| 1128 LookupResult lookup; | 1138 LookupResult lookup; |
| 1129 LookupForRead(*object, *name, &lookup); | 1139 LookupForRead(*object, *name, &lookup); |
| 1130 | 1140 |
| 1131 // If we did not find a property, check if we need to throw an exception. | 1141 // If we did not find a property, check if we need to throw an exception. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 | 1216 |
| 1207 | 1217 |
| 1208 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, | 1218 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, |
| 1209 Handle<Object> object, Handle<String> name) { | 1219 Handle<Object> object, Handle<String> name) { |
| 1210 // Bail out if we didn't find a result. | 1220 // Bail out if we didn't find a result. |
| 1211 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; | 1221 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; |
| 1212 | 1222 |
| 1213 if (!object->IsJSObject()) return; | 1223 if (!object->IsJSObject()) return; |
| 1214 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1224 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1215 | 1225 |
| 1216 if (HasNormalObjectsInPrototypeChain(lookup, *object)) return; | 1226 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return; |
| 1217 | 1227 |
| 1218 // Compute the code stub for this load. | 1228 // Compute the code stub for this load. |
| 1219 MaybeObject* maybe_code = NULL; | 1229 MaybeObject* maybe_code = NULL; |
| 1220 Object* code; | 1230 Object* code; |
| 1221 | 1231 |
| 1222 if (state == UNINITIALIZED) { | 1232 if (state == UNINITIALIZED) { |
| 1223 // This is the first time we execute this inline cache. | 1233 // This is the first time we execute this inline cache. |
| 1224 // Set the target to the pre monomorphic stub to delay | 1234 // Set the target to the pre monomorphic stub to delay |
| 1225 // setting the monomorphic state. | 1235 // setting the monomorphic state. |
| 1226 maybe_code = pre_monomorphic_stub(); | 1236 maybe_code = pre_monomorphic_stub(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 return TypeError("non_object_property_store", object, name); | 1332 return TypeError("non_object_property_store", object, name); |
| 1323 } | 1333 } |
| 1324 | 1334 |
| 1325 // Ignore stores where the receiver is not a JSObject. | 1335 // Ignore stores where the receiver is not a JSObject. |
| 1326 if (!object->IsJSObject()) return *value; | 1336 if (!object->IsJSObject()) return *value; |
| 1327 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1337 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1328 | 1338 |
| 1329 // Check if the given name is an array index. | 1339 // Check if the given name is an array index. |
| 1330 uint32_t index; | 1340 uint32_t index; |
| 1331 if (name->AsArrayIndex(&index)) { | 1341 if (name->AsArrayIndex(&index)) { |
| 1332 HandleScope scope; | 1342 HandleScope scope(isolate()); |
| 1333 Handle<Object> result = SetElement(receiver, index, value); | 1343 Handle<Object> result = SetElement(receiver, index, value); |
| 1334 if (result.is_null()) return Failure::Exception(); | 1344 if (result.is_null()) return Failure::Exception(); |
| 1335 return *value; | 1345 return *value; |
| 1336 } | 1346 } |
| 1337 | 1347 |
| 1338 // Use specialized code for setting the length of arrays. | 1348 // Use specialized code for setting the length of arrays. |
| 1339 if (receiver->IsJSArray() | 1349 if (receiver->IsJSArray() |
| 1340 && name->Equals(HEAP->length_symbol()) | 1350 && name->Equals(isolate()->heap()->length_symbol()) |
| 1341 && receiver->AllowsSetElementsLength()) { | 1351 && receiver->AllowsSetElementsLength()) { |
| 1342 #ifdef DEBUG | 1352 #ifdef DEBUG |
| 1343 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); | 1353 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); |
| 1344 #endif | 1354 #endif |
| 1345 Code* target = isolate()->builtins()->builtin( | 1355 Code* target = isolate()->builtins()->builtin( |
| 1346 Builtins::StoreIC_ArrayLength); | 1356 Builtins::StoreIC_ArrayLength); |
| 1347 set_target(target); | 1357 set_target(target); |
| 1348 return receiver->SetProperty(*name, *value, NONE); | 1358 return receiver->SetProperty(*name, *value, NONE); |
| 1349 } | 1359 } |
| 1350 | 1360 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1443 MaybeObject* maybe_code = NULL; | 1453 MaybeObject* maybe_code = NULL; |
| 1444 Object* code = NULL; | 1454 Object* code = NULL; |
| 1445 switch (type) { | 1455 switch (type) { |
| 1446 case FIELD: { | 1456 case FIELD: { |
| 1447 maybe_code = isolate()->stub_cache()->ComputeStoreField( | 1457 maybe_code = isolate()->stub_cache()->ComputeStoreField( |
| 1448 *name, *receiver, lookup->GetFieldIndex()); | 1458 *name, *receiver, lookup->GetFieldIndex()); |
| 1449 break; | 1459 break; |
| 1450 } | 1460 } |
| 1451 case MAP_TRANSITION: { | 1461 case MAP_TRANSITION: { |
| 1452 if (lookup->GetAttributes() != NONE) return; | 1462 if (lookup->GetAttributes() != NONE) return; |
| 1453 HandleScope scope; | 1463 HandleScope scope(isolate()); |
| 1454 ASSERT(type == MAP_TRANSITION); | 1464 ASSERT(type == MAP_TRANSITION); |
| 1455 Handle<Map> transition(lookup->GetTransitionMap()); | 1465 Handle<Map> transition(lookup->GetTransitionMap()); |
| 1456 int index = transition->PropertyIndexFor(*name); | 1466 int index = transition->PropertyIndexFor(*name); |
| 1457 maybe_code = isolate()->stub_cache()->ComputeStoreField( | 1467 maybe_code = isolate()->stub_cache()->ComputeStoreField( |
| 1458 *name, *receiver, index, *transition); | 1468 *name, *receiver, index, *transition); |
| 1459 break; | 1469 break; |
| 1460 } | 1470 } |
| 1461 case NORMAL: { | 1471 case NORMAL: { |
| 1462 if (receiver->IsGlobalObject()) { | 1472 if (receiver->IsGlobalObject()) { |
| 1463 // The stub generated for the global object picks the value directly | 1473 // The stub generated for the global object picks the value directly |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 return TypeError("non_object_property_store", object, name); | 1539 return TypeError("non_object_property_store", object, name); |
| 1530 } | 1540 } |
| 1531 | 1541 |
| 1532 // Ignore stores where the receiver is not a JSObject. | 1542 // Ignore stores where the receiver is not a JSObject. |
| 1533 if (!object->IsJSObject()) return *value; | 1543 if (!object->IsJSObject()) return *value; |
| 1534 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1544 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1535 | 1545 |
| 1536 // Check if the given name is an array index. | 1546 // Check if the given name is an array index. |
| 1537 uint32_t index; | 1547 uint32_t index; |
| 1538 if (name->AsArrayIndex(&index)) { | 1548 if (name->AsArrayIndex(&index)) { |
| 1539 HandleScope scope; | 1549 HandleScope scope(isolate()); |
| 1540 Handle<Object> result = SetElement(receiver, index, value); | 1550 Handle<Object> result = SetElement(receiver, index, value); |
| 1541 if (result.is_null()) return Failure::Exception(); | 1551 if (result.is_null()) return Failure::Exception(); |
| 1542 return *value; | 1552 return *value; |
| 1543 } | 1553 } |
| 1544 | 1554 |
| 1545 // Lookup the property locally in the receiver. | 1555 // Lookup the property locally in the receiver. |
| 1546 LookupResult lookup; | 1556 LookupResult lookup; |
| 1547 receiver->LocalLookup(*name, &lookup); | 1557 receiver->LocalLookup(*name, &lookup); |
| 1548 | 1558 |
| 1549 // Update inline cache and stub cache. | 1559 // Update inline cache and stub cache. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 Object* code = NULL; | 1620 Object* code = NULL; |
| 1611 | 1621 |
| 1612 switch (type) { | 1622 switch (type) { |
| 1613 case FIELD: { | 1623 case FIELD: { |
| 1614 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( | 1624 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( |
| 1615 *name, *receiver, lookup->GetFieldIndex()); | 1625 *name, *receiver, lookup->GetFieldIndex()); |
| 1616 break; | 1626 break; |
| 1617 } | 1627 } |
| 1618 case MAP_TRANSITION: { | 1628 case MAP_TRANSITION: { |
| 1619 if (lookup->GetAttributes() == NONE) { | 1629 if (lookup->GetAttributes() == NONE) { |
| 1620 HandleScope scope; | 1630 HandleScope scope(isolate()); |
| 1621 ASSERT(type == MAP_TRANSITION); | 1631 ASSERT(type == MAP_TRANSITION); |
| 1622 Handle<Map> transition(lookup->GetTransitionMap()); | 1632 Handle<Map> transition(lookup->GetTransitionMap()); |
| 1623 int index = transition->PropertyIndexFor(*name); | 1633 int index = transition->PropertyIndexFor(*name); |
| 1624 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( | 1634 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( |
| 1625 *name, *receiver, index, *transition); | 1635 *name, *receiver, index, *transition); |
| 1626 break; | 1636 break; |
| 1627 } | 1637 } |
| 1628 // fall through. | 1638 // fall through. |
| 1629 } | 1639 } |
| 1630 default: { | 1640 default: { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1651 #ifdef DEBUG | 1661 #ifdef DEBUG |
| 1652 TraceIC("KeyedStoreIC", name, state, target()); | 1662 TraceIC("KeyedStoreIC", name, state, target()); |
| 1653 #endif | 1663 #endif |
| 1654 } | 1664 } |
| 1655 | 1665 |
| 1656 | 1666 |
| 1657 // ---------------------------------------------------------------------------- | 1667 // ---------------------------------------------------------------------------- |
| 1658 // Static IC stub generators. | 1668 // Static IC stub generators. |
| 1659 // | 1669 // |
| 1660 | 1670 |
| 1661 static JSFunction* CompileFunction(JSFunction* function, | 1671 static JSFunction* CompileFunction(Isolate* isolate, |
| 1672 JSFunction* function, |
| 1662 InLoopFlag in_loop) { | 1673 InLoopFlag in_loop) { |
| 1663 // Compile now with optimization. | 1674 // Compile now with optimization. |
| 1664 HandleScope scope; | 1675 HandleScope scope(isolate); |
| 1665 Handle<JSFunction> function_handle(function); | 1676 Handle<JSFunction> function_handle(function, isolate); |
| 1666 if (in_loop == IN_LOOP) { | 1677 if (in_loop == IN_LOOP) { |
| 1667 CompileLazyInLoop(function_handle, CLEAR_EXCEPTION); | 1678 CompileLazyInLoop(function_handle, CLEAR_EXCEPTION); |
| 1668 } else { | 1679 } else { |
| 1669 CompileLazy(function_handle, CLEAR_EXCEPTION); | 1680 CompileLazy(function_handle, CLEAR_EXCEPTION); |
| 1670 } | 1681 } |
| 1671 return *function_handle; | 1682 return *function_handle; |
| 1672 } | 1683 } |
| 1673 | 1684 |
| 1674 | 1685 |
| 1675 // Used from ic-<arch>.cc. | 1686 // Used from ic-<arch>.cc. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1688 // The first time the inline cache is updated may be the first time the | 1699 // The first time the inline cache is updated may be the first time the |
| 1689 // function it references gets called. If the function was lazily compiled | 1700 // function it references gets called. If the function was lazily compiled |
| 1690 // then the first call will trigger a compilation. We check for this case | 1701 // then the first call will trigger a compilation. We check for this case |
| 1691 // and we do the compilation immediately, instead of waiting for the stub | 1702 // and we do the compilation immediately, instead of waiting for the stub |
| 1692 // currently attached to the JSFunction object to trigger compilation. We | 1703 // currently attached to the JSFunction object to trigger compilation. We |
| 1693 // do this in the case where we know that the inline cache is inside a loop, | 1704 // do this in the case where we know that the inline cache is inside a loop, |
| 1694 // because then we know that we want to optimize the function. | 1705 // because then we know that we want to optimize the function. |
| 1695 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { | 1706 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { |
| 1696 return result; | 1707 return result; |
| 1697 } | 1708 } |
| 1698 return CompileFunction(JSFunction::cast(result), ic.target()->ic_in_loop()); | 1709 return CompileFunction(isolate, |
| 1710 JSFunction::cast(result), |
| 1711 ic.target()->ic_in_loop()); |
| 1699 } | 1712 } |
| 1700 | 1713 |
| 1701 | 1714 |
| 1702 // Used from ic-<arch>.cc. | 1715 // Used from ic-<arch>.cc. |
| 1703 MUST_USE_RESULT MaybeObject* KeyedCallIC_Miss(RUNTIME_CALLING_CONVENTION) { | 1716 MUST_USE_RESULT MaybeObject* KeyedCallIC_Miss(RUNTIME_CALLING_CONVENTION) { |
| 1704 RUNTIME_GET_ISOLATE; | 1717 RUNTIME_GET_ISOLATE; |
| 1705 NoHandleAllocation na; | 1718 NoHandleAllocation na; |
| 1706 ASSERT(args.length() == 2); | 1719 ASSERT(args.length() == 2); |
| 1707 KeyedCallIC ic(isolate); | 1720 KeyedCallIC ic(isolate); |
| 1708 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 1721 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 1709 Object* result; | 1722 Object* result; |
| 1710 { MaybeObject* maybe_result = | 1723 { MaybeObject* maybe_result = |
| 1711 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); | 1724 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); |
| 1712 if (!maybe_result->ToObject(&result)) return maybe_result; | 1725 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1713 } | 1726 } |
| 1714 | 1727 |
| 1715 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { | 1728 if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { |
| 1716 return result; | 1729 return result; |
| 1717 } | 1730 } |
| 1718 return CompileFunction(JSFunction::cast(result), ic.target()->ic_in_loop()); | 1731 return CompileFunction(isolate, |
| 1732 JSFunction::cast(result), |
| 1733 ic.target()->ic_in_loop()); |
| 1719 } | 1734 } |
| 1720 | 1735 |
| 1721 | 1736 |
| 1722 // Used from ic-<arch>.cc. | 1737 // Used from ic-<arch>.cc. |
| 1723 MUST_USE_RESULT MaybeObject* LoadIC_Miss(RUNTIME_CALLING_CONVENTION) { | 1738 MUST_USE_RESULT MaybeObject* LoadIC_Miss(RUNTIME_CALLING_CONVENTION) { |
| 1724 RUNTIME_GET_ISOLATE; | 1739 RUNTIME_GET_ISOLATE; |
| 1725 NoHandleAllocation na; | 1740 NoHandleAllocation na; |
| 1726 ASSERT(args.length() == 2); | 1741 ASSERT(args.length() == 2); |
| 1727 LoadIC ic(isolate); | 1742 LoadIC ic(isolate); |
| 1728 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 1743 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1878 | 1893 |
| 1879 | 1894 |
| 1880 // defined in code-stubs-<arch>.cc | 1895 // defined in code-stubs-<arch>.cc |
| 1881 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info); | 1896 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info); |
| 1882 | 1897 |
| 1883 | 1898 |
| 1884 MUST_USE_RESULT MaybeObject* BinaryOp_Patch(RUNTIME_CALLING_CONVENTION) { | 1899 MUST_USE_RESULT MaybeObject* BinaryOp_Patch(RUNTIME_CALLING_CONVENTION) { |
| 1885 RUNTIME_GET_ISOLATE; | 1900 RUNTIME_GET_ISOLATE; |
| 1886 ASSERT(args.length() == 5); | 1901 ASSERT(args.length() == 5); |
| 1887 | 1902 |
| 1888 HandleScope scope; | 1903 HandleScope scope(isolate); |
| 1889 Handle<Object> left = args.at<Object>(0); | 1904 Handle<Object> left = args.at<Object>(0); |
| 1890 Handle<Object> right = args.at<Object>(1); | 1905 Handle<Object> right = args.at<Object>(1); |
| 1891 int key = Smi::cast(args[2])->value(); | 1906 int key = Smi::cast(args[2])->value(); |
| 1892 Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value()); | 1907 Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value()); |
| 1893 BinaryOpIC::TypeInfo previous_type = | 1908 BinaryOpIC::TypeInfo previous_type = |
| 1894 static_cast<BinaryOpIC::TypeInfo>(Smi::cast(args[4])->value()); | 1909 static_cast<BinaryOpIC::TypeInfo>(Smi::cast(args[4])->value()); |
| 1895 | 1910 |
| 1896 BinaryOpIC::TypeInfo type = BinaryOpIC::GetTypeInfo(*left, *right); | 1911 BinaryOpIC::TypeInfo type = BinaryOpIC::GetTypeInfo(*left, *right); |
| 1897 Handle<Code> code = GetBinaryOpStub(key, type); | 1912 Handle<Code> code = GetBinaryOpStub(key, type); |
| 1898 if (!code.is_null()) { | 1913 if (!code.is_null()) { |
| 1899 BinaryOpIC ic(isolate); | 1914 BinaryOpIC ic(isolate); |
| 1900 ic.patch(*code); | 1915 ic.patch(*code); |
| 1901 if (FLAG_trace_ic) { | 1916 if (FLAG_trace_ic) { |
| 1902 PrintF("[BinaryOpIC (%s->%s)#%s]\n", | 1917 PrintF("[BinaryOpIC (%s->%s)#%s]\n", |
| 1903 BinaryOpIC::GetName(previous_type), | 1918 BinaryOpIC::GetName(previous_type), |
| 1904 BinaryOpIC::GetName(type), | 1919 BinaryOpIC::GetName(type), |
| 1905 Token::Name(op)); | 1920 Token::Name(op)); |
| 1906 } | 1921 } |
| 1907 } | 1922 } |
| 1908 | 1923 |
| 1909 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>( | 1924 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>( |
| 1910 isolate->thread_local_top()->context_->builtins()); | 1925 isolate->thread_local_top()->context_->builtins(), isolate); |
| 1911 Object* builtin = NULL; // Initialization calms down the compiler. | 1926 Object* builtin = NULL; // Initialization calms down the compiler. |
| 1912 switch (op) { | 1927 switch (op) { |
| 1913 case Token::ADD: | 1928 case Token::ADD: |
| 1914 builtin = builtins->javascript_builtin(Builtins::ADD); | 1929 builtin = builtins->javascript_builtin(Builtins::ADD); |
| 1915 break; | 1930 break; |
| 1916 case Token::SUB: | 1931 case Token::SUB: |
| 1917 builtin = builtins->javascript_builtin(Builtins::SUB); | 1932 builtin = builtins->javascript_builtin(Builtins::SUB); |
| 1918 break; | 1933 break; |
| 1919 case Token::MUL: | 1934 case Token::MUL: |
| 1920 builtin = builtins->javascript_builtin(Builtins::MUL); | 1935 builtin = builtins->javascript_builtin(Builtins::MUL); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1940 case Token::SAR: | 1955 case Token::SAR: |
| 1941 builtin = builtins->javascript_builtin(Builtins::SAR); | 1956 builtin = builtins->javascript_builtin(Builtins::SAR); |
| 1942 break; | 1957 break; |
| 1943 case Token::SHL: | 1958 case Token::SHL: |
| 1944 builtin = builtins->javascript_builtin(Builtins::SHL); | 1959 builtin = builtins->javascript_builtin(Builtins::SHL); |
| 1945 break; | 1960 break; |
| 1946 default: | 1961 default: |
| 1947 UNREACHABLE(); | 1962 UNREACHABLE(); |
| 1948 } | 1963 } |
| 1949 | 1964 |
| 1950 Handle<JSFunction> builtin_function(JSFunction::cast(builtin)); | 1965 Handle<JSFunction> builtin_function(JSFunction::cast(builtin), |
| 1966 isolate); |
| 1951 | 1967 |
| 1952 bool caught_exception; | 1968 bool caught_exception; |
| 1953 Object** builtin_args[] = { right.location() }; | 1969 Object** builtin_args[] = { right.location() }; |
| 1954 Handle<Object> result = Execution::Call(builtin_function, | 1970 Handle<Object> result = Execution::Call(builtin_function, |
| 1955 left, | 1971 left, |
| 1956 ARRAY_SIZE(builtin_args), | 1972 ARRAY_SIZE(builtin_args), |
| 1957 builtin_args, | 1973 builtin_args, |
| 1958 &caught_exception); | 1974 &caught_exception); |
| 1959 if (caught_exception) { | 1975 if (caught_exception) { |
| 1960 return Failure::Exception(); | 1976 return Failure::Exception(); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 if (FLAG_trace_ic) { | 2102 if (FLAG_trace_ic) { |
| 2087 PrintF("[TypeRecordingBinaryOpIC (%s->(%s->%s))#%s]\n", | 2103 PrintF("[TypeRecordingBinaryOpIC (%s->(%s->%s))#%s]\n", |
| 2088 TRBinaryOpIC::GetName(previous_type), | 2104 TRBinaryOpIC::GetName(previous_type), |
| 2089 TRBinaryOpIC::GetName(type), | 2105 TRBinaryOpIC::GetName(type), |
| 2090 TRBinaryOpIC::GetName(result_type), | 2106 TRBinaryOpIC::GetName(result_type), |
| 2091 Token::Name(op)); | 2107 Token::Name(op)); |
| 2092 } | 2108 } |
| 2093 } | 2109 } |
| 2094 | 2110 |
| 2095 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>( | 2111 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>( |
| 2096 isolate->thread_local_top()->context_->builtins()); | 2112 isolate->thread_local_top()->context_->builtins(), isolate); |
| 2097 Object* builtin = NULL; // Initialization calms down the compiler. | 2113 Object* builtin = NULL; // Initialization calms down the compiler. |
| 2098 switch (op) { | 2114 switch (op) { |
| 2099 case Token::ADD: | 2115 case Token::ADD: |
| 2100 builtin = builtins->javascript_builtin(Builtins::ADD); | 2116 builtin = builtins->javascript_builtin(Builtins::ADD); |
| 2101 break; | 2117 break; |
| 2102 case Token::SUB: | 2118 case Token::SUB: |
| 2103 builtin = builtins->javascript_builtin(Builtins::SUB); | 2119 builtin = builtins->javascript_builtin(Builtins::SUB); |
| 2104 break; | 2120 break; |
| 2105 case Token::MUL: | 2121 case Token::MUL: |
| 2106 builtin = builtins->javascript_builtin(Builtins::MUL); | 2122 builtin = builtins->javascript_builtin(Builtins::MUL); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2126 case Token::SAR: | 2142 case Token::SAR: |
| 2127 builtin = builtins->javascript_builtin(Builtins::SAR); | 2143 builtin = builtins->javascript_builtin(Builtins::SAR); |
| 2128 break; | 2144 break; |
| 2129 case Token::SHL: | 2145 case Token::SHL: |
| 2130 builtin = builtins->javascript_builtin(Builtins::SHL); | 2146 builtin = builtins->javascript_builtin(Builtins::SHL); |
| 2131 break; | 2147 break; |
| 2132 default: | 2148 default: |
| 2133 UNREACHABLE(); | 2149 UNREACHABLE(); |
| 2134 } | 2150 } |
| 2135 | 2151 |
| 2136 Handle<JSFunction> builtin_function(JSFunction::cast(builtin)); | 2152 Handle<JSFunction> builtin_function(JSFunction::cast(builtin), isolate); |
| 2137 | 2153 |
| 2138 bool caught_exception; | 2154 bool caught_exception; |
| 2139 Object** builtin_args[] = { right.location() }; | 2155 Object** builtin_args[] = { right.location() }; |
| 2140 Handle<Object> result = Execution::Call(builtin_function, | 2156 Handle<Object> result = Execution::Call(builtin_function, |
| 2141 left, | 2157 left, |
| 2142 ARRAY_SIZE(builtin_args), | 2158 ARRAY_SIZE(builtin_args), |
| 2143 builtin_args, | 2159 builtin_args, |
| 2144 &caught_exception); | 2160 &caught_exception); |
| 2145 if (caught_exception) { | 2161 if (caught_exception) { |
| 2146 return Failure::Exception(); | 2162 return Failure::Exception(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2206 #undef ADDR | 2222 #undef ADDR |
| 2207 }; | 2223 }; |
| 2208 | 2224 |
| 2209 | 2225 |
| 2210 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2226 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2211 return IC_utilities[id]; | 2227 return IC_utilities[id]; |
| 2212 } | 2228 } |
| 2213 | 2229 |
| 2214 | 2230 |
| 2215 } } // namespace v8::internal | 2231 } } // namespace v8::internal |
| OLD | NEW |