| 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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(Isolate* isolate) { | 244 Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(Isolate* isolate) { |
| 245 Factory* factory = isolate->factory(); | 245 Factory* factory = isolate->factory(); |
| 246 | 246 |
| 247 // Generate the new code. | 247 // Generate the new code. |
| 248 MacroAssembler masm(isolate, NULL, 256); | 248 MacroAssembler masm(isolate, NULL, 256); |
| 249 | 249 |
| 250 { | 250 { |
| 251 // Update the static counter each time a new code stub is generated. | 251 // Update the static counter each time a new code stub is generated. |
| 252 isolate->counters()->code_stubs()->Increment(); | 252 isolate->counters()->code_stubs()->Increment(); |
| 253 | 253 |
| 254 // Nested stubs are not allowed for leaves. | |
| 255 AllowStubCallsScope allow_scope(&masm, false); | |
| 256 | |
| 257 // Generate the code for the stub. | 254 // Generate the code for the stub. |
| 258 masm.set_generating_stub(true); | 255 masm.set_generating_stub(true); |
| 259 NoCurrentFrameScope scope(&masm); | 256 NoCurrentFrameScope scope(&masm); |
| 260 GenerateLightweightMiss(&masm); | 257 GenerateLightweightMiss(&masm); |
| 261 } | 258 } |
| 262 | 259 |
| 263 // Create the code object. | 260 // Create the code object. |
| 264 CodeDesc desc; | 261 CodeDesc desc; |
| 265 masm.GetCode(&desc); | 262 masm.GetCode(&desc); |
| 266 | 263 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE); | 462 isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE); |
| 466 | 463 |
| 467 for (int i = 0; i < object_size; i += kPointerSize) { | 464 for (int i = 0; i < object_size; i += kPointerSize) { |
| 468 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); | 465 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); |
| 469 Add<HStoreNamedField>(object, access, | 466 Add<HStoreNamedField>(object, access, |
| 470 Add<HLoadNamedField>(boilerplate, access)); | 467 Add<HLoadNamedField>(boilerplate, access)); |
| 471 } | 468 } |
| 472 | 469 |
| 473 ASSERT(FLAG_allocation_site_pretenuring || (size == object_size)); | 470 ASSERT(FLAG_allocation_site_pretenuring || (size == object_size)); |
| 474 if (FLAG_allocation_site_pretenuring) { | 471 if (FLAG_allocation_site_pretenuring) { |
| 475 BuildCreateAllocationMemento(object, object_size, allocation_site); | 472 BuildCreateAllocationMemento( |
| 473 object, Add<HConstant>(object_size), allocation_site); |
| 476 } | 474 } |
| 477 | 475 |
| 478 environment()->Push(object); | 476 environment()->Push(object); |
| 479 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); | 477 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); |
| 480 checker.End(); | 478 checker.End(); |
| 481 | 479 |
| 482 return environment()->Pop(); | 480 return environment()->Pop(); |
| 483 } | 481 } |
| 484 | 482 |
| 485 | 483 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 return DoGenerateCode(isolate, this); | 607 return DoGenerateCode(isolate, this); |
| 610 } | 608 } |
| 611 | 609 |
| 612 | 610 |
| 613 template<> | 611 template<> |
| 614 HValue* CodeStubGraphBuilder<KeyedArrayCallStub>::BuildCodeStub() { | 612 HValue* CodeStubGraphBuilder<KeyedArrayCallStub>::BuildCodeStub() { |
| 615 int argc = casted_stub()->argc() + 1; | 613 int argc = casted_stub()->argc() + 1; |
| 616 info()->set_parameter_count(argc); | 614 info()->set_parameter_count(argc); |
| 617 | 615 |
| 618 HValue* receiver = Add<HParameter>(1); | 616 HValue* receiver = Add<HParameter>(1); |
| 617 BuildCheckHeapObject(receiver); |
| 619 | 618 |
| 620 // Load the expected initial array map from the context. | 619 // Load the expected initial array map from the context. |
| 621 JSArrayBuilder array_builder(this, casted_stub()->elements_kind()); | 620 JSArrayBuilder array_builder(this, casted_stub()->elements_kind()); |
| 622 HValue* map = array_builder.EmitMapCode(); | 621 HValue* map = array_builder.EmitMapCode(); |
| 623 | 622 |
| 624 HValue* checked_receiver = Add<HCheckMapValue>(receiver, map); | 623 HValue* checked_receiver = Add<HCheckMapValue>(receiver, map); |
| 625 | 624 |
| 626 HValue* function = BuildUncheckedMonomorphicElementAccess( | 625 HValue* function = BuildUncheckedMonomorphicElementAccess( |
| 627 checked_receiver, GetParameter(0), | 626 checked_receiver, GetParameter(0), |
| 628 NULL, true, casted_stub()->elements_kind(), | 627 NULL, true, casted_stub()->elements_kind(), |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 : graph()->GetConstantUndefined(); | 889 : graph()->GetConstantUndefined(); |
| 891 } | 890 } |
| 892 | 891 |
| 893 | 892 |
| 894 Handle<Code> CompareNilICStub::GenerateCode(Isolate* isolate) { | 893 Handle<Code> CompareNilICStub::GenerateCode(Isolate* isolate) { |
| 895 return DoGenerateCode(isolate, this); | 894 return DoGenerateCode(isolate, this); |
| 896 } | 895 } |
| 897 | 896 |
| 898 | 897 |
| 899 template <> | 898 template <> |
| 900 HValue* CodeStubGraphBuilder<BinaryOpStub>::BuildCodeInitializedStub() { | 899 HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() { |
| 901 BinaryOpStub* stub = casted_stub(); | 900 BinaryOpIC::State state = casted_stub()->state(); |
| 902 HValue* left = GetParameter(0); | |
| 903 HValue* right = GetParameter(1); | |
| 904 | 901 |
| 905 Handle<Type> left_type = stub->GetLeftType(isolate()); | 902 HValue* left = GetParameter(BinaryOpICStub::kLeft); |
| 906 Handle<Type> right_type = stub->GetRightType(isolate()); | 903 HValue* right = GetParameter(BinaryOpICStub::kRight); |
| 907 Handle<Type> result_type = stub->GetResultType(isolate()); | 904 |
| 905 Handle<Type> left_type = state.GetLeftType(isolate()); |
| 906 Handle<Type> right_type = state.GetRightType(isolate()); |
| 907 Handle<Type> result_type = state.GetResultType(isolate()); |
| 908 | 908 |
| 909 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && | 909 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && |
| 910 (stub->HasSideEffects(isolate()) || !result_type->Is(Type::None()))); | 910 (state.HasSideEffects() || !result_type->Is(Type::None()))); |
| 911 | 911 |
| 912 HValue* result = NULL; | 912 HValue* result = NULL; |
| 913 if (stub->operation() == Token::ADD && | 913 if (state.op() == Token::ADD && |
| 914 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && | 914 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && |
| 915 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { | 915 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { |
| 916 // For the generic add stub a fast case for string addition is performance | 916 // For the generic add stub a fast case for string addition is performance |
| 917 // critical. | 917 // critical. |
| 918 if (left_type->Maybe(Type::String())) { | 918 if (left_type->Maybe(Type::String())) { |
| 919 IfBuilder if_leftisstring(this); | 919 IfBuilder if_leftisstring(this); |
| 920 if_leftisstring.If<HIsStringAndBranch>(left); | 920 if_leftisstring.If<HIsStringAndBranch>(left); |
| 921 if_leftisstring.Then(); | 921 if_leftisstring.Then(); |
| 922 { | 922 { |
| 923 Push(BuildBinaryOperation( | 923 Push(BuildBinaryOperation( |
| 924 stub->operation(), left, right, | 924 state.op(), left, right, |
| 925 handle(Type::String(), isolate()), right_type, | 925 handle(Type::String(), isolate()), right_type, |
| 926 result_type, stub->fixed_right_arg())); | 926 result_type, state.fixed_right_arg())); |
| 927 } | 927 } |
| 928 if_leftisstring.Else(); | 928 if_leftisstring.Else(); |
| 929 { | 929 { |
| 930 Push(BuildBinaryOperation( | 930 Push(BuildBinaryOperation( |
| 931 stub->operation(), left, right, | 931 state.op(), left, right, |
| 932 left_type, right_type, result_type, | 932 left_type, right_type, result_type, |
| 933 stub->fixed_right_arg())); | 933 state.fixed_right_arg())); |
| 934 } | 934 } |
| 935 if_leftisstring.End(); | 935 if_leftisstring.End(); |
| 936 result = Pop(); | 936 result = Pop(); |
| 937 } else { | 937 } else { |
| 938 IfBuilder if_rightisstring(this); | 938 IfBuilder if_rightisstring(this); |
| 939 if_rightisstring.If<HIsStringAndBranch>(right); | 939 if_rightisstring.If<HIsStringAndBranch>(right); |
| 940 if_rightisstring.Then(); | 940 if_rightisstring.Then(); |
| 941 { | 941 { |
| 942 Push(BuildBinaryOperation( | 942 Push(BuildBinaryOperation( |
| 943 stub->operation(), left, right, | 943 state.op(), left, right, |
| 944 left_type, handle(Type::String(), isolate()), | 944 left_type, handle(Type::String(), isolate()), |
| 945 result_type, stub->fixed_right_arg())); | 945 result_type, state.fixed_right_arg())); |
| 946 } | 946 } |
| 947 if_rightisstring.Else(); | 947 if_rightisstring.Else(); |
| 948 { | 948 { |
| 949 Push(BuildBinaryOperation( | 949 Push(BuildBinaryOperation( |
| 950 stub->operation(), left, right, | 950 state.op(), left, right, |
| 951 left_type, right_type, result_type, | 951 left_type, right_type, result_type, |
| 952 stub->fixed_right_arg())); | 952 state.fixed_right_arg())); |
| 953 } | 953 } |
| 954 if_rightisstring.End(); | 954 if_rightisstring.End(); |
| 955 result = Pop(); | 955 result = Pop(); |
| 956 } | 956 } |
| 957 } else { | 957 } else { |
| 958 result = BuildBinaryOperation( | 958 result = BuildBinaryOperation( |
| 959 stub->operation(), left, right, | 959 state.op(), left, right, |
| 960 left_type, right_type, result_type, | 960 left_type, right_type, result_type, |
| 961 stub->fixed_right_arg()); | 961 state.fixed_right_arg()); |
| 962 } | 962 } |
| 963 | 963 |
| 964 // If we encounter a generic argument, the number conversion is | 964 // If we encounter a generic argument, the number conversion is |
| 965 // observable, thus we cannot afford to bail out after the fact. | 965 // observable, thus we cannot afford to bail out after the fact. |
| 966 if (!stub->HasSideEffects(isolate())) { | 966 if (!state.HasSideEffects()) { |
| 967 if (result_type->Is(Type::Smi())) { | 967 if (result_type->Is(Type::Smi())) { |
| 968 if (stub->operation() == Token::SHR) { | 968 if (state.op() == Token::SHR) { |
| 969 // TODO(olivf) Replace this by a SmiTagU Instruction. | 969 // TODO(olivf) Replace this by a SmiTagU Instruction. |
| 970 // 0x40000000: this number would convert to negative when interpreting | 970 // 0x40000000: this number would convert to negative when interpreting |
| 971 // the register as signed value; | 971 // the register as signed value; |
| 972 IfBuilder if_of(this); | 972 IfBuilder if_of(this); |
| 973 if_of.IfNot<HCompareNumericAndBranch>(result, | 973 if_of.IfNot<HCompareNumericAndBranch>(result, |
| 974 Add<HConstant>(static_cast<int>(SmiValuesAre32Bits() | 974 Add<HConstant>(static_cast<int>(SmiValuesAre32Bits() |
| 975 ? 0x80000000 : 0x40000000)), Token::EQ_STRICT); | 975 ? 0x80000000 : 0x40000000)), Token::EQ_STRICT); |
| 976 if_of.Then(); | 976 if_of.Then(); |
| 977 if_of.ElseDeopt("UInt->Smi oveflow"); | 977 if_of.ElseDeopt("UInt->Smi oveflow"); |
| 978 if_of.End(); | 978 if_of.End(); |
| 979 } | 979 } |
| 980 } | 980 } |
| 981 result = EnforceNumberType(result, result_type); | 981 result = EnforceNumberType(result, result_type); |
| 982 } | 982 } |
| 983 | 983 |
| 984 // Reuse the double box of one of the operands if we are allowed to (i.e. | 984 // Reuse the double box of one of the operands if we are allowed to (i.e. |
| 985 // chained binops). | 985 // chained binops). |
| 986 if (stub->CanReuseDoubleBox()) { | 986 if (state.CanReuseDoubleBox()) { |
| 987 HValue* operand = (stub->mode() == OVERWRITE_LEFT) ? left : right; | 987 HValue* operand = (state.mode() == OVERWRITE_LEFT) ? left : right; |
| 988 IfBuilder if_heap_number(this); | 988 IfBuilder if_heap_number(this); |
| 989 if_heap_number.IfNot<HIsSmiAndBranch>(operand); | 989 if_heap_number.IfNot<HIsSmiAndBranch>(operand); |
| 990 if_heap_number.Then(); | 990 if_heap_number.Then(); |
| 991 Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result); | 991 Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result); |
| 992 Push(operand); | 992 Push(operand); |
| 993 if_heap_number.Else(); | 993 if_heap_number.Else(); |
| 994 Push(result); | 994 Push(result); |
| 995 if_heap_number.End(); | 995 if_heap_number.End(); |
| 996 result = Pop(); | 996 result = Pop(); |
| 997 } | 997 } |
| 998 | 998 |
| 999 return result; | 999 return result; |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 | 1002 |
| 1003 Handle<Code> BinaryOpStub::GenerateCode(Isolate* isolate) { | 1003 Handle<Code> BinaryOpICStub::GenerateCode(Isolate* isolate) { |
| 1004 return DoGenerateCode(isolate, this); | 1004 return DoGenerateCode(isolate, this); |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 | 1007 |
| 1008 template <> | 1008 template <> |
| 1009 HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() { | 1009 HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() { |
| 1010 NewStringAddStub* stub = casted_stub(); | 1010 NewStringAddStub* stub = casted_stub(); |
| 1011 StringAddFlags flags = stub->flags(); | 1011 StringAddFlags flags = stub->flags(); |
| 1012 PretenureFlag pretenure_flag = stub->pretenure_flag(); | 1012 PretenureFlag pretenure_flag = stub->pretenure_flag(); |
| 1013 | 1013 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 return BuildUncheckedDictionaryElementLoad(receiver, key); | 1331 return BuildUncheckedDictionaryElementLoad(receiver, key); |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 | 1334 |
| 1335 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) { | 1335 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) { |
| 1336 return DoGenerateCode(isolate, this); | 1336 return DoGenerateCode(isolate, this); |
| 1337 } | 1337 } |
| 1338 | 1338 |
| 1339 | 1339 |
| 1340 } } // namespace v8::internal | 1340 } } // namespace v8::internal |
| OLD | NEW |