| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #include "src/v8.h" |     5 #include "src/v8.h" | 
|     6  |     6  | 
|     7 #if V8_TARGET_ARCH_ARM |     7 #if V8_TARGET_ARCH_ARM | 
|     8  |     8  | 
|     9 #include "src/bootstrapper.h" |     9 #include "src/bootstrapper.h" | 
|    10 #include "src/code-stubs.h" |    10 #include "src/code-stubs.h" | 
|    11 #include "src/regexp-macro-assembler.h" |    11 #include "src/regexp-macro-assembler.h" | 
|    12 #include "src/stub-cache.h" |    12 #include "src/stub-cache.h" | 
|    13  |    13  | 
|    14 namespace v8 { |    14 namespace v8 { | 
|    15 namespace internal { |    15 namespace internal { | 
|    16  |    16  | 
|    17  |    17  | 
|    18 void FastNewClosureStub::InitializeInterfaceDescriptor( |    18 void FastNewClosureStub::InitializeInterfaceDescriptor( | 
|    19     CodeStubInterfaceDescriptor* descriptor) { |    19     CodeStubInterfaceDescriptor* descriptor) { | 
|    20   Register registers[] = { cp, r2 }; |    20   Register registers[] = { cp, r2 }; | 
|    21   descriptor->Initialize( |    21   descriptor->Initialize( | 
|    22       ARRAY_SIZE(registers), registers, |    22       MajorKey(), ARRAY_SIZE(registers), registers, | 
|    23       Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry); |    23       Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry); | 
|    24 } |    24 } | 
|    25  |    25  | 
|    26  |    26  | 
|    27 void FastNewContextStub::InitializeInterfaceDescriptor( |    27 void FastNewContextStub::InitializeInterfaceDescriptor( | 
|    28     CodeStubInterfaceDescriptor* descriptor) { |    28     CodeStubInterfaceDescriptor* descriptor) { | 
|    29   Register registers[] = { cp, r1 }; |    29   Register registers[] = { cp, r1 }; | 
|    30   descriptor->Initialize(ARRAY_SIZE(registers), registers); |    30   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); | 
|    31 } |    31 } | 
|    32  |    32  | 
|    33  |    33  | 
|    34 void ToNumberStub::InitializeInterfaceDescriptor( |    34 void ToNumberStub::InitializeInterfaceDescriptor( | 
|    35     CodeStubInterfaceDescriptor* descriptor) { |    35     CodeStubInterfaceDescriptor* descriptor) { | 
|    36   Register registers[] = { cp, r0 }; |    36   Register registers[] = { cp, r0 }; | 
|    37   descriptor->Initialize(ARRAY_SIZE(registers), registers); |    37   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); | 
|    38 } |    38 } | 
|    39  |    39  | 
|    40  |    40  | 
|    41 void NumberToStringStub::InitializeInterfaceDescriptor( |    41 void NumberToStringStub::InitializeInterfaceDescriptor( | 
|    42     CodeStubInterfaceDescriptor* descriptor) { |    42     CodeStubInterfaceDescriptor* descriptor) { | 
|    43   Register registers[] = { cp, r0 }; |    43   Register registers[] = { cp, r0 }; | 
|    44   descriptor->Initialize( |    44   descriptor->Initialize( | 
|    45       ARRAY_SIZE(registers), registers, |    45       MajorKey(), ARRAY_SIZE(registers), registers, | 
|    46       Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry); |    46       Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry); | 
|    47 } |    47 } | 
|    48  |    48  | 
|    49  |    49  | 
|    50 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( |    50 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | 
|    51     CodeStubInterfaceDescriptor* descriptor) { |    51     CodeStubInterfaceDescriptor* descriptor) { | 
|    52   Register registers[] = { cp, r3, r2, r1 }; |    52   Register registers[] = { cp, r3, r2, r1 }; | 
|    53   Representation representations[] = { |    53   Representation representations[] = { | 
|    54     Representation::Tagged(), |    54     Representation::Tagged(), | 
|    55     Representation::Tagged(), |    55     Representation::Tagged(), | 
|    56     Representation::Smi(), |    56     Representation::Smi(), | 
|    57     Representation::Tagged() }; |    57     Representation::Tagged() }; | 
|    58   descriptor->Initialize( |    58   descriptor->Initialize( | 
|    59       ARRAY_SIZE(registers), registers, |    59       MajorKey(), ARRAY_SIZE(registers), registers, | 
|    60       Runtime::FunctionForId( |    60       Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry, | 
|    61           Runtime::kCreateArrayLiteralStubBailout)->entry, |  | 
|    62       representations); |    61       representations); | 
|    63 } |    62 } | 
|    64  |    63  | 
|    65  |    64  | 
|    66 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( |    65 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | 
|    67     CodeStubInterfaceDescriptor* descriptor) { |    66     CodeStubInterfaceDescriptor* descriptor) { | 
|    68   Register registers[] = { cp, r3, r2, r1, r0 }; |    67   Register registers[] = { cp, r3, r2, r1, r0 }; | 
|    69   descriptor->Initialize( |    68   descriptor->Initialize( | 
|    70       ARRAY_SIZE(registers), registers, |    69       MajorKey(), ARRAY_SIZE(registers), registers, | 
|    71       Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry); |    70       Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry); | 
|    72 } |    71 } | 
|    73  |    72  | 
|    74  |    73  | 
|    75 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |    74 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 
|    76     CodeStubInterfaceDescriptor* descriptor) { |    75     CodeStubInterfaceDescriptor* descriptor) { | 
|    77   Register registers[] = { cp, r2, r3 }; |    76   Register registers[] = { cp, r2, r3 }; | 
|    78   descriptor->Initialize(ARRAY_SIZE(registers), registers); |    77   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); | 
|    79 } |    78 } | 
|    80  |    79  | 
|    81  |    80  | 
 |    81 void InstanceofStub::InitializeInterfaceDescriptor( | 
 |    82     Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { | 
 |    83   Register registers[] = {cp, left(), right()}; | 
 |    84   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); | 
 |    85 } | 
 |    86  | 
 |    87  | 
 |    88 void CallFunctionStub::InitializeInterfaceDescriptor( | 
 |    89     Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { | 
 |    90   // r1  function    the function to call | 
 |    91   Register registers[] = {cp, r1}; | 
 |    92   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); | 
 |    93 } | 
 |    94  | 
 |    95  | 
 |    96 void CallConstructStub::InitializeInterfaceDescriptor( | 
 |    97     Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { | 
 |    98   // r0 : number of arguments | 
 |    99   // r1 : the function to call | 
 |   100   // r2 : feedback vector | 
 |   101   // r3 : (only if r2 is not the megamorphic symbol) slot in feedback | 
 |   102   //      vector (Smi) | 
 |   103   // TODO(turbofan): So far we don't gather type feedback and hence skip the | 
 |   104   // slot parameter, but ArrayConstructStub needs the vector to be undefined. | 
 |   105   Register registers[] = {cp, r0, r1, r2}; | 
 |   106   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); | 
 |   107 } | 
 |   108  | 
 |   109  | 
|    82 void RegExpConstructResultStub::InitializeInterfaceDescriptor( |   110 void RegExpConstructResultStub::InitializeInterfaceDescriptor( | 
|    83     CodeStubInterfaceDescriptor* descriptor) { |   111     CodeStubInterfaceDescriptor* descriptor) { | 
|    84   Register registers[] = { cp, r2, r1, r0 }; |   112   Register registers[] = { cp, r2, r1, r0 }; | 
|    85   descriptor->Initialize( |   113   descriptor->Initialize( | 
|    86       ARRAY_SIZE(registers), registers, |   114       MajorKey(), ARRAY_SIZE(registers), registers, | 
|    87       Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); |   115       Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); | 
|    88 } |   116 } | 
|    89  |   117  | 
|    90  |   118  | 
|    91 void TransitionElementsKindStub::InitializeInterfaceDescriptor( |   119 void TransitionElementsKindStub::InitializeInterfaceDescriptor( | 
|    92     CodeStubInterfaceDescriptor* descriptor) { |   120     CodeStubInterfaceDescriptor* descriptor) { | 
|    93   Register registers[] = { cp, r0, r1 }; |   121   Register registers[] = { cp, r0, r1 }; | 
|    94   Address entry = |   122   Address entry = | 
|    95       Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry; |   123       Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry; | 
|    96   descriptor->Initialize(ARRAY_SIZE(registers), registers, |   124   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, | 
|    97                          FUNCTION_ADDR(entry)); |   125                          FUNCTION_ADDR(entry)); | 
|    98 } |   126 } | 
|    99  |   127  | 
|   100  |   128  | 
|   101 void CompareNilICStub::InitializeInterfaceDescriptor( |   129 void CompareNilICStub::InitializeInterfaceDescriptor( | 
|   102     CodeStubInterfaceDescriptor* descriptor) { |   130     CodeStubInterfaceDescriptor* descriptor) { | 
|   103   Register registers[] = { cp, r0 }; |   131   Register registers[] = { cp, r0 }; | 
|   104   descriptor->Initialize(ARRAY_SIZE(registers), registers, |   132   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, | 
|   105                          FUNCTION_ADDR(CompareNilIC_Miss)); |   133                          FUNCTION_ADDR(CompareNilIC_Miss)); | 
|   106   descriptor->SetMissHandler( |   134   descriptor->SetMissHandler( | 
|   107       ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate())); |   135       ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate())); | 
|   108 } |   136 } | 
|   109  |   137  | 
|   110  |   138  | 
|   111 const Register InterfaceDescriptor::ContextRegister() { return cp; } |   139 const Register InterfaceDescriptor::ContextRegister() { return cp; } | 
|   112  |   140  | 
|   113  |   141  | 
|   114 static void InitializeArrayConstructorDescriptor( |   142 static void InitializeArrayConstructorDescriptor( | 
|   115     CodeStubInterfaceDescriptor* descriptor, |   143     CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor, | 
|   116     int constant_stack_parameter_count) { |   144     int constant_stack_parameter_count) { | 
|   117   // register state |   145   // register state | 
|   118   // cp -- context |   146   // cp -- context | 
|   119   // r0 -- number of arguments |   147   // r0 -- number of arguments | 
|   120   // r1 -- function |   148   // r1 -- function | 
|   121   // r2 -- allocation site with elements kind |   149   // r2 -- allocation site with elements kind | 
|   122   Address deopt_handler = Runtime::FunctionForId( |   150   Address deopt_handler = Runtime::FunctionForId( | 
|   123       Runtime::kArrayConstructor)->entry; |   151       Runtime::kArrayConstructor)->entry; | 
|   124  |   152  | 
|   125   if (constant_stack_parameter_count == 0) { |   153   if (constant_stack_parameter_count == 0) { | 
|   126     Register registers[] = { cp, r1, r2 }; |   154     Register registers[] = { cp, r1, r2 }; | 
|   127     descriptor->Initialize(ARRAY_SIZE(registers), registers, |   155     descriptor->Initialize(major, ARRAY_SIZE(registers), registers, | 
|   128                            deopt_handler, |   156                            deopt_handler, NULL, constant_stack_parameter_count, | 
|   129                            NULL, |  | 
|   130                            constant_stack_parameter_count, |  | 
|   131                            JS_FUNCTION_STUB_MODE); |   157                            JS_FUNCTION_STUB_MODE); | 
|   132   } else { |   158   } else { | 
|   133     // stack param count needs (constructor pointer, and single argument) |   159     // stack param count needs (constructor pointer, and single argument) | 
|   134     Register registers[] = { cp, r1, r2, r0 }; |   160     Register registers[] = { cp, r1, r2, r0 }; | 
|   135     Representation representations[] = { |   161     Representation representations[] = { | 
|   136         Representation::Tagged(), |   162         Representation::Tagged(), | 
|   137         Representation::Tagged(), |   163         Representation::Tagged(), | 
|   138         Representation::Tagged(), |   164         Representation::Tagged(), | 
|   139         Representation::Integer32() }; |   165         Representation::Integer32() }; | 
|   140     descriptor->Initialize(ARRAY_SIZE(registers), registers, |   166     descriptor->Initialize(major, ARRAY_SIZE(registers), registers, r0, | 
|   141                            r0, |   167                            deopt_handler, representations, | 
|   142                            deopt_handler, |  | 
|   143                            representations, |  | 
|   144                            constant_stack_parameter_count, |   168                            constant_stack_parameter_count, | 
|   145                            JS_FUNCTION_STUB_MODE, |   169                            JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); | 
|   146                            PASS_ARGUMENTS); |  | 
|   147   } |   170   } | 
|   148 } |   171 } | 
|   149  |   172  | 
|   150  |   173  | 
|   151 static void InitializeInternalArrayConstructorDescriptor( |   174 static void InitializeInternalArrayConstructorDescriptor( | 
|   152     CodeStubInterfaceDescriptor* descriptor, |   175     CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor, | 
|   153     int constant_stack_parameter_count) { |   176     int constant_stack_parameter_count) { | 
|   154   // register state |   177   // register state | 
|   155   // cp -- context |   178   // cp -- context | 
|   156   // r0 -- number of arguments |   179   // r0 -- number of arguments | 
|   157   // r1 -- constructor function |   180   // r1 -- constructor function | 
|   158   Address deopt_handler = Runtime::FunctionForId( |   181   Address deopt_handler = Runtime::FunctionForId( | 
|   159       Runtime::kInternalArrayConstructor)->entry; |   182       Runtime::kInternalArrayConstructor)->entry; | 
|   160  |   183  | 
|   161   if (constant_stack_parameter_count == 0) { |   184   if (constant_stack_parameter_count == 0) { | 
|   162     Register registers[] = { cp, r1 }; |   185     Register registers[] = { cp, r1 }; | 
|   163     descriptor->Initialize(ARRAY_SIZE(registers), registers, |   186     descriptor->Initialize(major, ARRAY_SIZE(registers), registers, | 
|   164                            deopt_handler, |   187                            deopt_handler, NULL, constant_stack_parameter_count, | 
|   165                            NULL, |  | 
|   166                            constant_stack_parameter_count, |  | 
|   167                            JS_FUNCTION_STUB_MODE); |   188                            JS_FUNCTION_STUB_MODE); | 
|   168   } else { |   189   } else { | 
|   169     // stack param count needs (constructor pointer, and single argument) |   190     // stack param count needs (constructor pointer, and single argument) | 
|   170     Register registers[] = { cp, r1, r0 }; |   191     Register registers[] = { cp, r1, r0 }; | 
|   171     Representation representations[] = { |   192     Representation representations[] = { | 
|   172         Representation::Tagged(), |   193         Representation::Tagged(), | 
|   173         Representation::Tagged(), |   194         Representation::Tagged(), | 
|   174         Representation::Integer32() }; |   195         Representation::Integer32() }; | 
|   175     descriptor->Initialize(ARRAY_SIZE(registers), registers, |   196     descriptor->Initialize(major, ARRAY_SIZE(registers), registers, r0, | 
|   176                            r0, |   197                            deopt_handler, representations, | 
|   177                            deopt_handler, |  | 
|   178                            representations, |  | 
|   179                            constant_stack_parameter_count, |   198                            constant_stack_parameter_count, | 
|   180                            JS_FUNCTION_STUB_MODE, |   199                            JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); | 
|   181                            PASS_ARGUMENTS); |  | 
|   182   } |   200   } | 
|   183 } |   201 } | 
|   184  |   202  | 
|   185  |   203  | 
|   186 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |   204 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 
|   187     CodeStubInterfaceDescriptor* descriptor) { |   205     CodeStubInterfaceDescriptor* descriptor) { | 
|   188   InitializeArrayConstructorDescriptor(descriptor, 0); |   206   InitializeArrayConstructorDescriptor(MajorKey(), descriptor, 0); | 
|   189 } |   207 } | 
|   190  |   208  | 
|   191  |   209  | 
|   192 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |   210 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 
|   193     CodeStubInterfaceDescriptor* descriptor) { |   211     CodeStubInterfaceDescriptor* descriptor) { | 
|   194   InitializeArrayConstructorDescriptor(descriptor, 1); |   212   InitializeArrayConstructorDescriptor(MajorKey(), descriptor, 1); | 
|   195 } |   213 } | 
|   196  |   214  | 
|   197  |   215  | 
|   198 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |   216 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 
|   199     CodeStubInterfaceDescriptor* descriptor) { |   217     CodeStubInterfaceDescriptor* descriptor) { | 
|   200   InitializeArrayConstructorDescriptor(descriptor, -1); |   218   InitializeArrayConstructorDescriptor(MajorKey(), descriptor, -1); | 
|   201 } |   219 } | 
|   202  |   220  | 
|   203  |   221  | 
|   204 void ToBooleanStub::InitializeInterfaceDescriptor( |   222 void ToBooleanStub::InitializeInterfaceDescriptor( | 
|   205     CodeStubInterfaceDescriptor* descriptor) { |   223     CodeStubInterfaceDescriptor* descriptor) { | 
|   206   Register registers[] = { cp, r0 }; |   224   Register registers[] = { cp, r0 }; | 
|   207   descriptor->Initialize(ARRAY_SIZE(registers), registers, |   225   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, | 
|   208                          FUNCTION_ADDR(ToBooleanIC_Miss)); |   226                          FUNCTION_ADDR(ToBooleanIC_Miss)); | 
|   209   descriptor->SetMissHandler( |   227   descriptor->SetMissHandler( | 
|   210       ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate())); |   228       ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate())); | 
|   211 } |   229 } | 
|   212  |   230  | 
|   213  |   231  | 
|   214 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |   232 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 
|   215     CodeStubInterfaceDescriptor* descriptor) { |   233     CodeStubInterfaceDescriptor* descriptor) { | 
|   216   InitializeInternalArrayConstructorDescriptor(descriptor, 0); |   234   InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 0); | 
|   217 } |   235 } | 
|   218  |   236  | 
|   219  |   237  | 
|   220 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |   238 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 
|   221     CodeStubInterfaceDescriptor* descriptor) { |   239     CodeStubInterfaceDescriptor* descriptor) { | 
|   222   InitializeInternalArrayConstructorDescriptor(descriptor, 1); |   240   InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 1); | 
|   223 } |   241 } | 
|   224  |   242  | 
|   225  |   243  | 
|   226 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |   244 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 
|   227     CodeStubInterfaceDescriptor* descriptor) { |   245     CodeStubInterfaceDescriptor* descriptor) { | 
|   228   InitializeInternalArrayConstructorDescriptor(descriptor, -1); |   246   InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, -1); | 
|   229 } |   247 } | 
|   230  |   248  | 
|   231  |   249  | 
|   232 void BinaryOpICStub::InitializeInterfaceDescriptor( |   250 void BinaryOpICStub::InitializeInterfaceDescriptor( | 
|   233     CodeStubInterfaceDescriptor* descriptor) { |   251     CodeStubInterfaceDescriptor* descriptor) { | 
|   234   Register registers[] = { cp, r1, r0 }; |   252   Register registers[] = { cp, r1, r0 }; | 
|   235   descriptor->Initialize(ARRAY_SIZE(registers), registers, |   253   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, | 
|   236                          FUNCTION_ADDR(BinaryOpIC_Miss)); |   254                          FUNCTION_ADDR(BinaryOpIC_Miss)); | 
|   237   descriptor->SetMissHandler( |   255   descriptor->SetMissHandler( | 
|   238       ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate())); |   256       ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate())); | 
|   239 } |   257 } | 
|   240  |   258  | 
|   241  |   259  | 
|   242 void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor( |   260 void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor( | 
|   243     CodeStubInterfaceDescriptor* descriptor) { |   261     CodeStubInterfaceDescriptor* descriptor) { | 
|   244   Register registers[] = { cp, r2, r1, r0 }; |   262   Register registers[] = { cp, r2, r1, r0 }; | 
|   245   descriptor->Initialize(ARRAY_SIZE(registers), registers, |   263   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, | 
|   246                          FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite)); |   264                          FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite)); | 
|   247 } |   265 } | 
|   248  |   266  | 
|   249  |   267  | 
|   250 void StringAddStub::InitializeInterfaceDescriptor( |   268 void StringAddStub::InitializeInterfaceDescriptor( | 
|   251     CodeStubInterfaceDescriptor* descriptor) { |   269     CodeStubInterfaceDescriptor* descriptor) { | 
|   252   Register registers[] = { cp, r1, r0 }; |   270   Register registers[] = { cp, r1, r0 }; | 
|   253   descriptor->Initialize( |   271   descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, | 
|   254       ARRAY_SIZE(registers), registers, |   272                          Runtime::FunctionForId(Runtime::kStringAdd)->entry); | 
|   255       Runtime::FunctionForId(Runtime::kStringAdd)->entry); |  | 
|   256 } |   273 } | 
|   257  |   274  | 
|   258  |   275  | 
|   259 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { |   276 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { | 
|   260   static PlatformInterfaceDescriptor default_descriptor = |   277   static PlatformInterfaceDescriptor default_descriptor = | 
|   261       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS); |   278       PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS); | 
|   262  |   279  | 
|   263   static PlatformInterfaceDescriptor noInlineDescriptor = |   280   static PlatformInterfaceDescriptor noInlineDescriptor = | 
|   264       PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS); |   281       PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS); | 
|   265  |   282  | 
| (...skipping 1399 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1665 // Expected input (depending on whether args are in registers or on the stack): |  1682 // Expected input (depending on whether args are in registers or on the stack): | 
|  1666 // * object: r0 or at sp + 1 * kPointerSize. |  1683 // * object: r0 or at sp + 1 * kPointerSize. | 
|  1667 // * function: r1 or at sp. |  1684 // * function: r1 or at sp. | 
|  1668 // |  1685 // | 
|  1669 // An inlined call site may have been generated before calling this stub. |  1686 // An inlined call site may have been generated before calling this stub. | 
|  1670 // In this case the offset to the inline sites to patch are passed in r5 and r6. |  1687 // In this case the offset to the inline sites to patch are passed in r5 and r6. | 
|  1671 // (See LCodeGen::DoInstanceOfKnownGlobal) |  1688 // (See LCodeGen::DoInstanceOfKnownGlobal) | 
|  1672 void InstanceofStub::Generate(MacroAssembler* masm) { |  1689 void InstanceofStub::Generate(MacroAssembler* masm) { | 
|  1673   // Call site inlining and patching implies arguments in registers. |  1690   // Call site inlining and patching implies arguments in registers. | 
|  1674   ASSERT(HasArgsInRegisters() || !HasCallSiteInlineCheck()); |  1691   ASSERT(HasArgsInRegisters() || !HasCallSiteInlineCheck()); | 
|  1675   // ReturnTrueFalse is only implemented for inlined call sites. |  | 
|  1676   ASSERT(!ReturnTrueFalseObject() || HasCallSiteInlineCheck()); |  | 
|  1677  |  1692  | 
|  1678   // Fixed register usage throughout the stub: |  1693   // Fixed register usage throughout the stub: | 
|  1679   const Register object = r0;  // Object (lhs). |  1694   const Register object = r0;  // Object (lhs). | 
|  1680   Register map = r3;  // Map of the object. |  1695   Register map = r3;  // Map of the object. | 
|  1681   const Register function = r1;  // Function (rhs). |  1696   const Register function = r1;  // Function (rhs). | 
|  1682   const Register prototype = r4;  // Prototype of the function. |  1697   const Register prototype = r4;  // Prototype of the function. | 
|  1683   const Register scratch = r2; |  1698   const Register scratch = r2; | 
|  1684  |  1699  | 
|  1685   Label slow, loop, is_instance, is_not_instance, not_js_object; |  1700   Label slow, loop, is_instance, is_not_instance, not_js_object; | 
|  1686  |  1701  | 
|  1687   if (!HasArgsInRegisters()) { |  1702   if (!HasArgsInRegisters()) { | 
|  1688     __ ldr(object, MemOperand(sp, 1 * kPointerSize)); |  1703     __ ldr(object, MemOperand(sp, 1 * kPointerSize)); | 
|  1689     __ ldr(function, MemOperand(sp, 0)); |  1704     __ ldr(function, MemOperand(sp, 0)); | 
|  1690   } |  1705   } | 
|  1691  |  1706  | 
|  1692   // Check that the left hand is a JS object and load map. |  1707   // Check that the left hand is a JS object and load map. | 
|  1693   __ JumpIfSmi(object, ¬_js_object); |  1708   __ JumpIfSmi(object, ¬_js_object); | 
|  1694   __ IsObjectJSObjectType(object, map, scratch, ¬_js_object); |  1709   __ IsObjectJSObjectType(object, map, scratch, ¬_js_object); | 
|  1695  |  1710  | 
|  1696   // If there is a call site cache don't look in the global cache, but do the |  1711   // If there is a call site cache don't look in the global cache, but do the | 
|  1697   // real lookup and update the call site cache. |  1712   // real lookup and update the call site cache. | 
|  1698   if (!HasCallSiteInlineCheck()) { |  1713   if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) { | 
|  1699     Label miss; |  1714     Label miss; | 
|  1700     __ CompareRoot(function, Heap::kInstanceofCacheFunctionRootIndex); |  1715     __ CompareRoot(function, Heap::kInstanceofCacheFunctionRootIndex); | 
|  1701     __ b(ne, &miss); |  1716     __ b(ne, &miss); | 
|  1702     __ CompareRoot(map, Heap::kInstanceofCacheMapRootIndex); |  1717     __ CompareRoot(map, Heap::kInstanceofCacheMapRootIndex); | 
|  1703     __ b(ne, &miss); |  1718     __ b(ne, &miss); | 
|  1704     __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); |  1719     __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); | 
|  1705     __ Ret(HasArgsInRegisters() ? 0 : 2); |  1720     __ Ret(HasArgsInRegisters() ? 0 : 2); | 
|  1706  |  1721  | 
|  1707     __ bind(&miss); |  1722     __ bind(&miss); | 
|  1708   } |  1723   } | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1744   // Loop through the prototype chain looking for the function prototype. |  1759   // Loop through the prototype chain looking for the function prototype. | 
|  1745   __ LoadRoot(scratch2, Heap::kNullValueRootIndex); |  1760   __ LoadRoot(scratch2, Heap::kNullValueRootIndex); | 
|  1746   __ bind(&loop); |  1761   __ bind(&loop); | 
|  1747   __ cmp(scratch, Operand(prototype)); |  1762   __ cmp(scratch, Operand(prototype)); | 
|  1748   __ b(eq, &is_instance); |  1763   __ b(eq, &is_instance); | 
|  1749   __ cmp(scratch, scratch2); |  1764   __ cmp(scratch, scratch2); | 
|  1750   __ b(eq, &is_not_instance); |  1765   __ b(eq, &is_not_instance); | 
|  1751   __ ldr(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset)); |  1766   __ ldr(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset)); | 
|  1752   __ ldr(scratch, FieldMemOperand(scratch, Map::kPrototypeOffset)); |  1767   __ ldr(scratch, FieldMemOperand(scratch, Map::kPrototypeOffset)); | 
|  1753   __ jmp(&loop); |  1768   __ jmp(&loop); | 
 |  1769   Factory* factory = isolate()->factory(); | 
|  1754  |  1770  | 
|  1755   __ bind(&is_instance); |  1771   __ bind(&is_instance); | 
|  1756   if (!HasCallSiteInlineCheck()) { |  1772   if (!HasCallSiteInlineCheck()) { | 
|  1757     __ mov(r0, Operand(Smi::FromInt(0))); |  1773     __ mov(r0, Operand(Smi::FromInt(0))); | 
|  1758     __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); |  1774     __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); | 
 |  1775     if (ReturnTrueFalseObject()) { | 
 |  1776       __ Move(r0, factory->true_value()); | 
 |  1777     } | 
|  1759   } else { |  1778   } else { | 
|  1760     // Patch the call site to return true. |  1779     // Patch the call site to return true. | 
|  1761     __ LoadRoot(r0, Heap::kTrueValueRootIndex); |  1780     __ LoadRoot(r0, Heap::kTrueValueRootIndex); | 
|  1762     // The bool_load_offset was stored in r6 |  1781     // The bool_load_offset was stored in r6 | 
|  1763     //   (See LCodeGen::DoDeferredLInstanceOfKnownGlobal). |  1782     //   (See LCodeGen::DoDeferredLInstanceOfKnownGlobal). | 
|  1764     const Register bool_load_offset = r6; |  1783     const Register bool_load_offset = r6; | 
|  1765     __ sub(r9, lr, bool_load_offset); |  1784     __ sub(r9, lr, bool_load_offset); | 
|  1766     // Get the boolean result location in scratch and patch it. |  1785     // Get the boolean result location in scratch and patch it. | 
|  1767     __ GetRelocatedValueLocation(r9, scratch, scratch2); |  1786     __ GetRelocatedValueLocation(r9, scratch, scratch2); | 
|  1768     __ str(r0, MemOperand(scratch)); |  1787     __ str(r0, MemOperand(scratch)); | 
|  1769  |  1788  | 
|  1770     if (!ReturnTrueFalseObject()) { |  1789     if (!ReturnTrueFalseObject()) { | 
|  1771       __ mov(r0, Operand(Smi::FromInt(0))); |  1790       __ mov(r0, Operand(Smi::FromInt(0))); | 
|  1772     } |  1791     } | 
|  1773   } |  1792   } | 
|  1774   __ Ret(HasArgsInRegisters() ? 0 : 2); |  1793   __ Ret(HasArgsInRegisters() ? 0 : 2); | 
|  1775  |  1794  | 
|  1776   __ bind(&is_not_instance); |  1795   __ bind(&is_not_instance); | 
|  1777   if (!HasCallSiteInlineCheck()) { |  1796   if (!HasCallSiteInlineCheck()) { | 
|  1778     __ mov(r0, Operand(Smi::FromInt(1))); |  1797     __ mov(r0, Operand(Smi::FromInt(1))); | 
|  1779     __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); |  1798     __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); | 
 |  1799     if (ReturnTrueFalseObject()) { | 
 |  1800       __ Move(r0, factory->false_value()); | 
 |  1801     } | 
|  1780   } else { |  1802   } else { | 
|  1781     // Patch the call site to return false. |  1803     // Patch the call site to return false. | 
|  1782     __ LoadRoot(r0, Heap::kFalseValueRootIndex); |  1804     __ LoadRoot(r0, Heap::kFalseValueRootIndex); | 
|  1783     // The bool_load_offset was stored in r6 |  1805     // The bool_load_offset was stored in r6 | 
|  1784     //   (See LCodeGen::DoDeferredLInstanceOfKnownGlobal). |  1806     //   (See LCodeGen::DoDeferredLInstanceOfKnownGlobal). | 
|  1785     const Register bool_load_offset = r6; |  1807     const Register bool_load_offset = r6; | 
|  1786     __ sub(r9, lr, bool_load_offset); |  1808     __ sub(r9, lr, bool_load_offset); | 
|  1787     ; |  1809     ; | 
|  1788     // Get the boolean result location in scratch and patch it. |  1810     // Get the boolean result location in scratch and patch it. | 
|  1789     __ GetRelocatedValueLocation(r9, scratch, scratch2); |  1811     __ GetRelocatedValueLocation(r9, scratch, scratch2); | 
|  1790     __ str(r0, MemOperand(scratch)); |  1812     __ str(r0, MemOperand(scratch)); | 
|  1791  |  1813  | 
|  1792     if (!ReturnTrueFalseObject()) { |  1814     if (!ReturnTrueFalseObject()) { | 
|  1793       __ mov(r0, Operand(Smi::FromInt(1))); |  1815       __ mov(r0, Operand(Smi::FromInt(1))); | 
|  1794     } |  1816     } | 
|  1795   } |  1817   } | 
|  1796   __ Ret(HasArgsInRegisters() ? 0 : 2); |  1818   __ Ret(HasArgsInRegisters() ? 0 : 2); | 
|  1797  |  1819  | 
|  1798   Label object_not_null, object_not_null_or_smi; |  1820   Label object_not_null, object_not_null_or_smi; | 
|  1799   __ bind(¬_js_object); |  1821   __ bind(¬_js_object); | 
|  1800   // Before null, smi and string value checks, check that the rhs is a function |  1822   // Before null, smi and string value checks, check that the rhs is a function | 
|  1801   // as for a non-function rhs an exception needs to be thrown. |  1823   // as for a non-function rhs an exception needs to be thrown. | 
|  1802   __ JumpIfSmi(function, &slow); |  1824   __ JumpIfSmi(function, &slow); | 
|  1803   __ CompareObjectType(function, scratch2, scratch, JS_FUNCTION_TYPE); |  1825   __ CompareObjectType(function, scratch2, scratch, JS_FUNCTION_TYPE); | 
|  1804   __ b(ne, &slow); |  1826   __ b(ne, &slow); | 
|  1805  |  1827  | 
|  1806   // Null is not instance of anything. |  1828   // Null is not instance of anything. | 
|  1807   __ cmp(scratch, Operand(isolate()->factory()->null_value())); |  1829   __ cmp(scratch, Operand(isolate()->factory()->null_value())); | 
|  1808   __ b(ne, &object_not_null); |  1830   __ b(ne, &object_not_null); | 
|  1809   __ mov(r0, Operand(Smi::FromInt(1))); |  1831   if (ReturnTrueFalseObject()) { | 
 |  1832     __ Move(r0, factory->false_value()); | 
 |  1833   } else { | 
 |  1834     __ mov(r0, Operand(Smi::FromInt(1))); | 
 |  1835   } | 
|  1810   __ Ret(HasArgsInRegisters() ? 0 : 2); |  1836   __ Ret(HasArgsInRegisters() ? 0 : 2); | 
|  1811  |  1837  | 
|  1812   __ bind(&object_not_null); |  1838   __ bind(&object_not_null); | 
|  1813   // Smi values are not instances of anything. |  1839   // Smi values are not instances of anything. | 
|  1814   __ JumpIfNotSmi(object, &object_not_null_or_smi); |  1840   __ JumpIfNotSmi(object, &object_not_null_or_smi); | 
|  1815   __ mov(r0, Operand(Smi::FromInt(1))); |  1841   if (ReturnTrueFalseObject()) { | 
 |  1842     __ Move(r0, factory->false_value()); | 
 |  1843   } else { | 
 |  1844     __ mov(r0, Operand(Smi::FromInt(1))); | 
 |  1845   } | 
|  1816   __ Ret(HasArgsInRegisters() ? 0 : 2); |  1846   __ Ret(HasArgsInRegisters() ? 0 : 2); | 
|  1817  |  1847  | 
|  1818   __ bind(&object_not_null_or_smi); |  1848   __ bind(&object_not_null_or_smi); | 
|  1819   // String values are not instances of anything. |  1849   // String values are not instances of anything. | 
|  1820   __ IsObjectJSStringType(object, scratch, &slow); |  1850   __ IsObjectJSStringType(object, scratch, &slow); | 
|  1821   __ mov(r0, Operand(Smi::FromInt(1))); |  1851   if (ReturnTrueFalseObject()) { | 
 |  1852     __ Move(r0, factory->false_value()); | 
 |  1853   } else { | 
 |  1854     __ mov(r0, Operand(Smi::FromInt(1))); | 
 |  1855   } | 
|  1822   __ Ret(HasArgsInRegisters() ? 0 : 2); |  1856   __ Ret(HasArgsInRegisters() ? 0 : 2); | 
|  1823  |  1857  | 
|  1824   // Slow-case.  Tail call builtin. |  1858   // Slow-case.  Tail call builtin. | 
|  1825   __ bind(&slow); |  1859   __ bind(&slow); | 
|  1826   if (!ReturnTrueFalseObject()) { |  1860   if (!ReturnTrueFalseObject()) { | 
|  1827     if (HasArgsInRegisters()) { |  1861     if (HasArgsInRegisters()) { | 
|  1828       __ Push(r0, r1); |  1862       __ Push(r0, r1); | 
|  1829     } |  1863     } | 
|  1830   __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |  1864   __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 
|  1831   } else { |  1865   } else { | 
| (...skipping 3233 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5065                               MemOperand(fp, 6 * kPointerSize), |  5099                               MemOperand(fp, 6 * kPointerSize), | 
|  5066                               NULL); |  5100                               NULL); | 
|  5067 } |  5101 } | 
|  5068  |  5102  | 
|  5069  |  5103  | 
|  5070 #undef __ |  5104 #undef __ | 
|  5071  |  5105  | 
|  5072 } }  // namespace v8::internal |  5106 } }  // namespace v8::internal | 
|  5073  |  5107  | 
|  5074 #endif  // V8_TARGET_ARCH_ARM |  5108 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW |