Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef V8_CALL_INTERFACE_DESCRIPTOR_H_ | 5 #ifndef V8_CALL_INTERFACE_DESCRIPTOR_H_ |
| 6 #define V8_CALL_INTERFACE_DESCRIPTOR_H_ | 6 #define V8_CALL_INTERFACE_DESCRIPTOR_H_ |
| 7 | 7 |
| 8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
| 9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 | 13 |
| 14 class PlatformInterfaceDescriptor; | 14 class PlatformInterfaceDescriptor; |
| 15 | 15 |
| 16 class CallInterfaceDescriptor { | 16 #define INTERFACE_DESCRIPTOR_LIST(V) \ |
| 17 V(Load) \ | |
| 18 V(Store) \ | |
| 19 V(ElementTransitionAndStore) \ | |
| 20 V(Instanceof) \ | |
| 21 V(VectorLoadIC) \ | |
| 22 V(FastNewClosure) \ | |
| 23 V(FastNewContext) \ | |
| 24 V(ToNumber) \ | |
| 25 V(NumberToString) \ | |
| 26 V(FastCloneShallowArray) \ | |
| 27 V(FastCloneShallowObject) \ | |
| 28 V(CreateAllocationSite) \ | |
| 29 V(CallFunction) \ | |
| 30 V(CallConstruct) \ | |
| 31 V(RegExpConstructResult) \ | |
| 32 V(TransitionElementsKind) \ | |
| 33 V(ArrayConstructorConstantArgCount) \ | |
| 34 V(ArrayConstructor) \ | |
| 35 V(InternalArrayConstructorConstantArgCount) \ | |
| 36 V(InternalArrayConstructor) \ | |
| 37 V(CompareNil) \ | |
| 38 V(ToBoolean) \ | |
| 39 V(BinaryOp) \ | |
| 40 V(BinaryOpWithAllocationSite) \ | |
| 41 V(StringAdd) \ | |
| 42 V(Keyed) \ | |
| 43 V(Named) \ | |
| 44 V(CallHandler) \ | |
| 45 V(ArgumentAdaptor) \ | |
| 46 V(ApiFunction) | |
| 47 | |
| 48 | |
| 49 class CallInterfaceDescriptorData { | |
| 17 public: | 50 public: |
| 18 CallInterfaceDescriptor() : register_param_count_(-1) {} | 51 CallInterfaceDescriptorData() : register_param_count_(-1) {} |
| 19 | 52 |
| 20 // A copy of the passed in registers and param_representations is made | 53 // A copy of the passed in registers and param_representations is made |
| 21 // and owned by the CallInterfaceDescriptor. | 54 // and owned by the CallInterfaceDescriptorData. |
| 22 | 55 |
| 23 // TODO(mvstanton): Instead of taking parallel arrays register and | 56 // TODO(mvstanton): Instead of taking parallel arrays register and |
| 24 // param_representations, how about a struct that puts the representation | 57 // param_representations, how about a struct that puts the representation |
| 25 // and register side by side (eg, RegRep(r1, Representation::Tagged()). | 58 // and register side by side (eg, RegRep(r1, Representation::Tagged()). |
| 26 // The same should go for the CodeStubInterfaceDescriptor class. | 59 // The same should go for the CodeStubInterfaceDescriptor class. |
| 27 void Initialize(int register_parameter_count, Register* registers, | 60 void Initialize(int register_parameter_count, Register* registers, |
| 28 Representation* param_representations, | 61 Representation* param_representations, |
| 29 PlatformInterfaceDescriptor* platform_descriptor = NULL); | 62 PlatformInterfaceDescriptor* platform_descriptor = NULL); |
| 30 | 63 |
| 31 bool IsInitialized() const { return register_param_count_ >= 0; } | 64 bool IsInitialized() const { return register_param_count_ >= 0; } |
| 32 | 65 |
| 33 int GetEnvironmentLength() const { return register_param_count_; } | 66 int register_param_count() const { return register_param_count_; } |
| 67 Register register_param(int index) const { return register_params_[index]; } | |
| 68 Register* register_params() const { return register_params_.get(); } | |
| 69 Representation register_param_representation(int index) const { | |
| 70 return register_param_representations_[index]; | |
| 71 } | |
| 72 Representation* register_param_representations() const { | |
| 73 return register_param_representations_.get(); | |
| 74 } | |
| 75 PlatformInterfaceDescriptor* platform_specific_descriptor() const { | |
| 76 return platform_specific_descriptor_; | |
| 77 } | |
| 34 | 78 |
| 35 int GetRegisterParameterCount() const { return register_param_count_; } | 79 private: |
| 80 int register_param_count_; | |
| 81 | |
| 82 // The Register params are allocated dynamically by the | |
| 83 // InterfaceDescriptor, and freed on destruction. This is because static | |
| 84 // arrays of Registers cause creation of runtime static initializers | |
| 85 // which we don't want. | |
| 86 SmartArrayPointer<Register> register_params_; | |
| 87 // Specifies Representations for the stub's parameter. Points to an array of | |
| 88 // Representations of the same length of the numbers of parameters to the | |
| 89 // stub, or if NULL (the default value), Representation of each parameter | |
| 90 // assumed to be Tagged(). | |
| 91 SmartArrayPointer<Representation> register_param_representations_; | |
| 92 | |
| 93 PlatformInterfaceDescriptor* platform_specific_descriptor_; | |
| 94 | |
| 95 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData); | |
| 96 }; | |
| 97 | |
| 98 | |
| 99 class CallDescriptors { | |
| 100 public: | |
| 101 enum Key { | |
| 102 #define DEF_ENUM(name) name, | |
| 103 INTERFACE_DESCRIPTOR_LIST(DEF_ENUM) | |
| 104 #undef DEF_ENUM | |
| 105 NUMBER_OF_DESCRIPTORS | |
| 106 }; | |
| 107 | |
| 108 static void InitializeForIsolate(Isolate* isolate); | |
| 109 }; | |
| 110 | |
| 111 | |
| 112 class CallInterfaceDescriptor { | |
| 113 public: | |
| 114 CallInterfaceDescriptor() : data_(NULL) {} | |
| 115 | |
| 116 CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key) | |
| 117 : data_(isolate->call_descriptor_data(key)) {} | |
|
Yang
2014/09/03 09:24:34
Can we simply
- fetch data from the isolate
- chec
| |
| 118 | |
| 119 bool IsInitialized() const { | |
| 120 return data() != NULL && data()->IsInitialized(); | |
|
Yang
2014/09/03 09:24:34
We then would also not need this any more. The con
| |
| 121 } | |
| 122 | |
| 123 int GetEnvironmentLength() const { return data()->register_param_count(); } | |
| 124 | |
| 125 int GetRegisterParameterCount() const { | |
| 126 return data()->register_param_count(); | |
| 127 } | |
| 36 | 128 |
| 37 Register GetParameterRegister(int index) const { | 129 Register GetParameterRegister(int index) const { |
| 38 return register_params_[index]; | 130 return data()->register_param(index); |
| 39 } | 131 } |
| 40 | 132 |
| 41 Representation GetParameterRepresentation(int index) const { | 133 Representation GetParameterRepresentation(int index) const { |
| 42 DCHECK(index < register_param_count_); | 134 DCHECK(index < data()->register_param_count()); |
| 43 if (register_param_representations_.get() == NULL) { | 135 if (data()->register_param_representations() == NULL) { |
| 44 return Representation::Tagged(); | 136 return Representation::Tagged(); |
| 45 } | 137 } |
| 46 | 138 |
| 47 return register_param_representations_[index]; | 139 return data()->register_param_representation(index); |
| 48 } | 140 } |
| 49 | 141 |
| 50 // "Environment" versions of parameter functions. The first register | 142 // "Environment" versions of parameter functions. The first register |
| 51 // parameter (context) is not included. | 143 // parameter (context) is not included. |
| 52 int GetEnvironmentParameterCount() const { | 144 int GetEnvironmentParameterCount() const { |
| 53 return GetEnvironmentLength() - 1; | 145 return GetEnvironmentLength() - 1; |
| 54 } | 146 } |
| 55 | 147 |
| 56 Register GetEnvironmentParameterRegister(int index) const { | 148 Register GetEnvironmentParameterRegister(int index) const { |
| 57 return GetParameterRegister(index + 1); | 149 return GetParameterRegister(index + 1); |
| 58 } | 150 } |
| 59 | 151 |
| 60 Representation GetEnvironmentParameterRepresentation(int index) const { | 152 Representation GetEnvironmentParameterRepresentation(int index) const { |
| 61 return GetParameterRepresentation(index + 1); | 153 return GetParameterRepresentation(index + 1); |
| 62 } | 154 } |
| 63 | 155 |
| 64 // Some platforms have extra information to associate with the descriptor. | 156 // Some platforms have extra information to associate with the descriptor. |
| 65 PlatformInterfaceDescriptor* platform_specific_descriptor() const { | 157 PlatformInterfaceDescriptor* platform_specific_descriptor() const { |
| 66 return platform_specific_descriptor_; | 158 return data()->platform_specific_descriptor(); |
| 67 } | 159 } |
| 68 | 160 |
| 69 static const Register ContextRegister(); | 161 static const Register ContextRegister(); |
| 70 | 162 |
| 163 protected: | |
| 164 const CallInterfaceDescriptorData* data() const { return data_; } | |
| 165 | |
| 166 static void InitializeData( | |
| 167 Isolate* isolate, CallDescriptors::Key key, int register_parameter_count, | |
| 168 Register* registers, Representation* param_representations, | |
| 169 PlatformInterfaceDescriptor* platform_descriptor = NULL) { | |
| 170 isolate->call_descriptor_data(key) | |
| 171 ->Initialize(register_parameter_count, registers, param_representations, | |
| 172 platform_descriptor); | |
| 173 } | |
| 174 | |
| 71 private: | 175 private: |
| 72 int register_param_count_; | 176 const CallInterfaceDescriptorData* data_; |
| 73 | 177 }; |
| 74 // The Register params are allocated dynamically by the | 178 |
| 75 // InterfaceDescriptor, and freed on destruction. This is because static | 179 |
| 76 // arrays of Registers cause creation of runtime static initializers | 180 #define DECLARE_DESCRIPTOR(name) \ |
| 77 // which we don't want. | 181 explicit name(Isolate* isolate) : CallInterfaceDescriptor(isolate, key()) {} \ |
| 78 SmartArrayPointer<Register> register_params_; | 182 static inline CallDescriptors::Key key(); \ |
| 79 // Specifies Representations for the stub's parameter. Points to an array of | 183 static void Initialize(Isolate* isolate); |
| 80 // Representations of the same length of the numbers of parameters to the | 184 |
| 81 // stub, or if NULL (the default value), Representation of each parameter | 185 |
| 82 // assumed to be Tagged(). | 186 class LoadDescriptor : public CallInterfaceDescriptor { |
| 83 SmartArrayPointer<Representation> register_param_representations_; | 187 public: |
| 84 | 188 DECLARE_DESCRIPTOR(LoadDescriptor) |
| 85 PlatformInterfaceDescriptor* platform_specific_descriptor_; | 189 |
| 86 | 190 enum ParameterIndices { kReceiverIndex, kNameIndex }; |
| 87 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptor); | 191 static const Register ReceiverRegister(); |
| 88 }; | 192 static const Register NameRegister(); |
| 89 | 193 }; |
| 90 | 194 |
| 91 enum CallDescriptorKey { | 195 |
| 92 LoadICCall, | 196 class StoreDescriptor : public CallInterfaceDescriptor { |
| 93 StoreICCall, | 197 public: |
| 94 ElementTransitionAndStoreCall, | 198 DECLARE_DESCRIPTOR(StoreDescriptor) |
| 95 InstanceofCall, | 199 |
| 96 VectorLoadICCall, | 200 enum ParameterIndices { |
| 97 FastNewClosureCall, | 201 kReceiverIndex, |
| 98 FastNewContextCall, | 202 kNameIndex, |
| 99 ToNumberCall, | 203 kValueIndex, |
| 100 NumberToStringCall, | 204 kParameterCount |
| 101 FastCloneShallowArrayCall, | 205 }; |
| 102 FastCloneShallowObjectCall, | 206 static const Register ReceiverRegister(); |
| 103 CreateAllocationSiteCall, | 207 static const Register NameRegister(); |
| 104 CallFunctionCall, | 208 static const Register ValueRegister(); |
| 105 CallConstructCall, | 209 }; |
| 106 RegExpConstructResultCall, | 210 |
| 107 TransitionElementsKindCall, | 211 |
| 108 ArrayConstructorConstantArgCountCall, | 212 class ElementTransitionAndStoreDescriptor : public CallInterfaceDescriptor { |
| 109 ArrayConstructorCall, | 213 public: |
| 110 InternalArrayConstructorConstantArgCountCall, | 214 DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor) |
| 111 InternalArrayConstructorCall, | 215 |
| 112 CompareNilCall, | 216 static const Register ReceiverRegister(); |
| 113 ToBooleanCall, | 217 static const Register NameRegister(); |
| 114 BinaryOpCall, | 218 static const Register ValueRegister(); |
| 115 BinaryOpWithAllocationSiteCall, | 219 static const Register MapRegister(); |
| 116 StringAddCall, | 220 }; |
| 117 KeyedCall, | 221 |
| 118 NamedCall, | 222 |
| 119 CallHandler, | 223 class InstanceofDescriptor : public CallInterfaceDescriptor { |
| 120 ArgumentAdaptorCall, | 224 public: |
| 121 ApiFunctionCall, | 225 DECLARE_DESCRIPTOR(InstanceofDescriptor) |
| 122 NUMBER_OF_CALL_DESCRIPTORS | 226 |
| 123 }; | 227 enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount }; |
| 124 | 228 static const Register left(); |
| 125 | 229 static const Register right(); |
| 126 class CallDescriptors { | 230 }; |
| 127 public: | 231 |
| 128 static void InitializeForIsolate(Isolate* isolate); | 232 |
| 129 | 233 class VectorLoadICDescriptor : public CallInterfaceDescriptor { |
| 130 private: | 234 public: |
| 131 static void InitializeForIsolateAllPlatforms(Isolate* isolate); | 235 DECLARE_DESCRIPTOR(VectorLoadICDescriptor) |
| 132 }; | 236 |
| 237 enum ParameterIndices { | |
| 238 kReceiverIndex, | |
| 239 kNameIndex, | |
| 240 kSlotIndex, | |
| 241 kVectorIndex, | |
| 242 kParameterCount | |
| 243 }; | |
| 244 | |
| 245 static const Register ReceiverRegister(); | |
| 246 static const Register NameRegister(); | |
| 247 static const Register SlotRegister(); | |
| 248 static const Register VectorRegister(); | |
| 249 }; | |
| 250 | |
| 251 | |
| 252 class FastNewClosureDescriptor : public CallInterfaceDescriptor { | |
| 253 public: | |
| 254 DECLARE_DESCRIPTOR(FastNewClosureDescriptor) | |
| 255 }; | |
| 256 | |
| 257 | |
| 258 class FastNewContextDescriptor : public CallInterfaceDescriptor { | |
| 259 public: | |
| 260 DECLARE_DESCRIPTOR(FastNewContextDescriptor) | |
| 261 }; | |
| 262 | |
| 263 | |
| 264 class ToNumberDescriptor : public CallInterfaceDescriptor { | |
| 265 public: | |
| 266 DECLARE_DESCRIPTOR(ToNumberDescriptor) | |
| 267 }; | |
| 268 | |
| 269 | |
| 270 class NumberToStringDescriptor : public CallInterfaceDescriptor { | |
| 271 public: | |
| 272 DECLARE_DESCRIPTOR(NumberToStringDescriptor) | |
| 273 }; | |
| 274 | |
| 275 | |
| 276 class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor { | |
| 277 public: | |
| 278 DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor) | |
| 279 }; | |
| 280 | |
| 281 | |
| 282 class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor { | |
| 283 public: | |
| 284 DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor) | |
| 285 }; | |
| 286 | |
| 287 | |
| 288 class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor { | |
| 289 public: | |
| 290 DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor) | |
| 291 }; | |
| 292 | |
| 293 | |
| 294 class CallFunctionDescriptor : public CallInterfaceDescriptor { | |
| 295 public: | |
| 296 DECLARE_DESCRIPTOR(CallFunctionDescriptor) | |
| 297 }; | |
| 298 | |
| 299 | |
| 300 class CallConstructDescriptor : public CallInterfaceDescriptor { | |
| 301 public: | |
| 302 DECLARE_DESCRIPTOR(CallConstructDescriptor) | |
| 303 }; | |
| 304 | |
| 305 | |
| 306 class RegExpConstructResultDescriptor : public CallInterfaceDescriptor { | |
| 307 public: | |
| 308 DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor) | |
| 309 }; | |
| 310 | |
| 311 | |
| 312 class TransitionElementsKindDescriptor : public CallInterfaceDescriptor { | |
| 313 public: | |
| 314 DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor) | |
| 315 }; | |
| 316 | |
| 317 | |
| 318 class ArrayConstructorConstantArgCountDescriptor | |
| 319 : public CallInterfaceDescriptor { | |
| 320 public: | |
| 321 DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor) | |
| 322 }; | |
| 323 | |
| 324 | |
| 325 class ArrayConstructorDescriptor : public CallInterfaceDescriptor { | |
| 326 public: | |
| 327 DECLARE_DESCRIPTOR(ArrayConstructorDescriptor) | |
| 328 }; | |
| 329 | |
| 330 | |
| 331 class InternalArrayConstructorConstantArgCountDescriptor | |
| 332 : public CallInterfaceDescriptor { | |
| 333 public: | |
| 334 DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor) | |
| 335 }; | |
| 336 | |
| 337 | |
| 338 class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor { | |
| 339 public: | |
| 340 DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor) | |
| 341 }; | |
| 342 | |
| 343 | |
| 344 class CompareNilDescriptor : public CallInterfaceDescriptor { | |
| 345 public: | |
| 346 DECLARE_DESCRIPTOR(CompareNilDescriptor) | |
| 347 }; | |
| 348 | |
| 349 | |
| 350 class ToBooleanDescriptor : public CallInterfaceDescriptor { | |
| 351 public: | |
| 352 DECLARE_DESCRIPTOR(ToBooleanDescriptor) | |
| 353 }; | |
| 354 | |
| 355 | |
| 356 class BinaryOpDescriptor : public CallInterfaceDescriptor { | |
| 357 public: | |
| 358 DECLARE_DESCRIPTOR(BinaryOpDescriptor) | |
| 359 }; | |
| 360 | |
| 361 | |
| 362 class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor { | |
| 363 public: | |
| 364 DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor) | |
| 365 }; | |
| 366 | |
| 367 | |
| 368 class StringAddDescriptor : public CallInterfaceDescriptor { | |
| 369 public: | |
| 370 DECLARE_DESCRIPTOR(StringAddDescriptor) | |
| 371 }; | |
| 372 | |
| 373 | |
| 374 class KeyedDescriptor : public CallInterfaceDescriptor { | |
| 375 public: | |
| 376 DECLARE_DESCRIPTOR(KeyedDescriptor) | |
| 377 }; | |
| 378 | |
| 379 | |
| 380 class NamedDescriptor : public CallInterfaceDescriptor { | |
| 381 public: | |
| 382 DECLARE_DESCRIPTOR(NamedDescriptor) | |
| 383 }; | |
| 384 | |
| 385 | |
| 386 class CallHandlerDescriptor : public CallInterfaceDescriptor { | |
| 387 public: | |
| 388 DECLARE_DESCRIPTOR(CallHandlerDescriptor) | |
| 389 }; | |
| 390 | |
| 391 | |
| 392 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor { | |
| 393 public: | |
| 394 DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor) | |
| 395 }; | |
| 396 | |
| 397 | |
| 398 class ApiFunctionDescriptor : public CallInterfaceDescriptor { | |
| 399 public: | |
| 400 DECLARE_DESCRIPTOR(ApiFunctionDescriptor) | |
| 401 }; | |
| 402 | |
| 403 #undef DECLARE_DESCRIPTOR | |
| 404 | |
| 405 | |
| 406 // We define the association between CallDescriptors::Key and the specialized | |
| 407 // descriptor here to reduce boilerplate and mistakes. | |
| 408 #define DEF_KEY(name) \ | |
| 409 CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; } | |
| 410 INTERFACE_DESCRIPTOR_LIST(DEF_KEY) | |
| 411 #undef DEF_KEY | |
| 133 } | 412 } |
| 134 } // namespace v8::internal | 413 } // namespace v8::internal |
| 135 | 414 |
| 415 | |
| 136 #if V8_TARGET_ARCH_ARM64 | 416 #if V8_TARGET_ARCH_ARM64 |
| 137 #include "src/arm64/interface-descriptors-arm64.h" | 417 #include "src/arm64/interface-descriptors-arm64.h" |
| 138 #elif V8_TARGET_ARCH_ARM | 418 #elif V8_TARGET_ARCH_ARM |
| 139 #include "src/arm/interface-descriptors-arm.h" | 419 #include "src/arm/interface-descriptors-arm.h" |
| 140 #endif | 420 #endif |
| 141 | 421 |
| 142 #endif // V8_CALL_INTERFACE_DESCRIPTOR_H_ | 422 #endif // V8_CALL_INTERFACE_DESCRIPTOR_H_ |
| OLD | NEW |