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 #ifndef V8_CODE_STUBS_H_ | 5 #ifndef V8_CODE_STUBS_H_ |
6 #define V8_CODE_STUBS_H_ | 6 #define V8_CODE_STUBS_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/assembler.h" | 9 #include "src/assembler.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 | 264 |
265 protected: | 265 protected: |
266 // Generates the assembler code for the stub. | 266 // Generates the assembler code for the stub. |
267 virtual void Generate(MacroAssembler* masm) = 0; | 267 virtual void Generate(MacroAssembler* masm) = 0; |
268 }; | 268 }; |
269 | 269 |
270 | 270 |
271 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; | 271 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; |
272 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; | 272 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; |
273 | 273 |
274 class CodeStubInterfaceDescriptor { | 274 |
| 275 class PlatformInterfaceDescriptor; |
| 276 |
| 277 |
| 278 class InterfaceDescriptor { |
| 279 public: |
| 280 bool IsInitialized() const { return register_param_count_ >= 0; } |
| 281 |
| 282 int GetEnvironmentLength() const { return register_param_count_; } |
| 283 |
| 284 int GetRegisterParameterCount() const { return register_param_count_; } |
| 285 |
| 286 Register GetParameterRegister(int index) const { |
| 287 return register_params_[index]; |
| 288 } |
| 289 |
| 290 Representation GetParameterRepresentation(int index) const { |
| 291 ASSERT(index < register_param_count_); |
| 292 if (register_param_representations_.get() == NULL) { |
| 293 return Representation::Tagged(); |
| 294 } |
| 295 |
| 296 return register_param_representations_[index]; |
| 297 } |
| 298 |
| 299 // "Environment" versions of parameter functions. The first register |
| 300 // parameter (context) is not included. |
| 301 int GetEnvironmentParameterCount() const { |
| 302 return GetEnvironmentLength() - 1; |
| 303 } |
| 304 |
| 305 Register GetEnvironmentParameterRegister(int index) const { |
| 306 return GetParameterRegister(index + 1); |
| 307 } |
| 308 |
| 309 Representation GetEnvironmentParameterRepresentation(int index) const { |
| 310 return GetParameterRepresentation(index + 1); |
| 311 } |
| 312 |
| 313 // Some platforms have extra information to associate with the descriptor. |
| 314 PlatformInterfaceDescriptor* platform_specific_descriptor() const { |
| 315 return platform_specific_descriptor_; |
| 316 } |
| 317 |
| 318 static const Register ContextRegister(); |
| 319 |
| 320 protected: |
| 321 InterfaceDescriptor(); |
| 322 virtual ~InterfaceDescriptor() {} |
| 323 |
| 324 void Initialize(int register_parameter_count, Register* registers, |
| 325 Representation* register_param_representations, |
| 326 PlatformInterfaceDescriptor* platform_descriptor = NULL); |
| 327 |
| 328 private: |
| 329 int register_param_count_; |
| 330 |
| 331 // The Register params are allocated dynamically by the |
| 332 // InterfaceDescriptor, and freed on destruction. This is because static |
| 333 // arrays of Registers cause creation of runtime static initializers |
| 334 // which we don't want. |
| 335 SmartArrayPointer<Register> register_params_; |
| 336 // Specifies Representations for the stub's parameter. Points to an array of |
| 337 // Representations of the same length of the numbers of parameters to the |
| 338 // stub, or if NULL (the default value), Representation of each parameter |
| 339 // assumed to be Tagged(). |
| 340 SmartArrayPointer<Representation> register_param_representations_; |
| 341 |
| 342 PlatformInterfaceDescriptor* platform_specific_descriptor_; |
| 343 |
| 344 DISALLOW_COPY_AND_ASSIGN(InterfaceDescriptor); |
| 345 }; |
| 346 |
| 347 |
| 348 class CodeStubInterfaceDescriptor: public InterfaceDescriptor { |
275 public: | 349 public: |
276 CodeStubInterfaceDescriptor(); | 350 CodeStubInterfaceDescriptor(); |
277 | 351 |
278 void Initialize(int register_parameter_count, Register* registers, | 352 void Initialize(int register_parameter_count, Register* registers, |
279 Address deoptimization_handler = NULL, | 353 Address deoptimization_handler = NULL, |
280 Representation* register_param_representations = NULL, | 354 Representation* register_param_representations = NULL, |
281 int hint_stack_parameter_count = -1, | 355 int hint_stack_parameter_count = -1, |
282 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE); | 356 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE); |
283 void Initialize(int register_parameter_count, Register* registers, | 357 void Initialize(int register_parameter_count, Register* registers, |
284 Register stack_parameter_count, | 358 Register stack_parameter_count, |
285 Address deoptimization_handler = NULL, | 359 Address deoptimization_handler = NULL, |
286 Representation* register_param_representations = NULL, | 360 Representation* register_param_representations = NULL, |
287 int hint_stack_parameter_count = -1, | 361 int hint_stack_parameter_count = -1, |
288 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE, | 362 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE, |
289 HandlerArgumentsMode handler_mode = DONT_PASS_ARGUMENTS); | 363 HandlerArgumentsMode handler_mode = DONT_PASS_ARGUMENTS); |
290 bool initialized() const { return register_param_count_ >= 0; } | |
291 | |
292 int environment_length() const { | |
293 return register_param_count_; | |
294 } | |
295 | 364 |
296 void SetMissHandler(ExternalReference handler) { | 365 void SetMissHandler(ExternalReference handler) { |
297 miss_handler_ = handler; | 366 miss_handler_ = handler; |
298 has_miss_handler_ = true; | 367 has_miss_handler_ = true; |
299 // Our miss handler infrastructure doesn't currently support | 368 // Our miss handler infrastructure doesn't currently support |
300 // variable stack parameter counts. | 369 // variable stack parameter counts. |
301 ASSERT(!stack_parameter_count_.is_valid()); | 370 ASSERT(!stack_parameter_count_.is_valid()); |
302 } | 371 } |
303 | 372 |
304 ExternalReference miss_handler() const { | 373 ExternalReference miss_handler() const { |
305 ASSERT(has_miss_handler_); | 374 ASSERT(has_miss_handler_); |
306 return miss_handler_; | 375 return miss_handler_; |
307 } | 376 } |
308 | 377 |
309 bool has_miss_handler() const { | 378 bool has_miss_handler() const { |
310 return has_miss_handler_; | 379 return has_miss_handler_; |
311 } | 380 } |
312 | 381 |
313 Register GetParameterRegister(int index) const { | 382 bool IsEnvironmentParameterCountRegister(int index) const { |
314 return register_params_[index]; | 383 return GetEnvironmentParameterRegister(index).is(stack_parameter_count_); |
315 } | |
316 | |
317 Representation GetRegisterParameterRepresentation(int index) const { | |
318 ASSERT(index < register_param_count_); | |
319 if (register_param_representations_.get() == NULL) { | |
320 return Representation::Tagged(); | |
321 } | |
322 | |
323 return register_param_representations_[index]; | |
324 } | |
325 | |
326 bool IsParameterCountRegister(int index) const { | |
327 return GetParameterRegister(index).is(stack_parameter_count_); | |
328 } | 384 } |
329 | 385 |
330 int GetHandlerParameterCount() const { | 386 int GetHandlerParameterCount() const { |
331 int params = environment_length(); | 387 int params = GetEnvironmentParameterCount(); |
332 if (handler_arguments_mode_ == PASS_ARGUMENTS) { | 388 if (handler_arguments_mode_ == PASS_ARGUMENTS) { |
333 params += 1; | 389 params += 1; |
334 } | 390 } |
335 return params; | 391 return params; |
336 } | 392 } |
337 | 393 |
338 int register_param_count() const { return register_param_count_; } | |
339 int hint_stack_parameter_count() const { return hint_stack_parameter_count_; } | 394 int hint_stack_parameter_count() const { return hint_stack_parameter_count_; } |
340 Register stack_parameter_count() const { return stack_parameter_count_; } | 395 Register stack_parameter_count() const { return stack_parameter_count_; } |
341 StubFunctionMode function_mode() const { return function_mode_; } | 396 StubFunctionMode function_mode() const { return function_mode_; } |
342 Address deoptimization_handler() const { return deoptimization_handler_; } | 397 Address deoptimization_handler() const { return deoptimization_handler_; } |
343 Representation* register_param_representations() const { | |
344 return register_param_representations_.get(); | |
345 } | |
346 | 398 |
347 private: | 399 private: |
348 int register_param_count_; | |
349 | |
350 Register stack_parameter_count_; | 400 Register stack_parameter_count_; |
351 // If hint_stack_parameter_count_ > 0, the code stub can optimize the | 401 // If hint_stack_parameter_count_ > 0, the code stub can optimize the |
352 // return sequence. Default value is -1, which means it is ignored. | 402 // return sequence. Default value is -1, which means it is ignored. |
353 int hint_stack_parameter_count_; | 403 int hint_stack_parameter_count_; |
354 StubFunctionMode function_mode_; | 404 StubFunctionMode function_mode_; |
355 // The Register params are allocated dynamically by the | |
356 // CodeStubInterfaceDescriptor, and freed on destruction. This is because | |
357 // static arrays of Registers cause creation of runtime static initializers | |
358 // which we don't want. | |
359 SmartArrayPointer<Register> register_params_; | |
360 // Specifies Representations for the stub's parameter. Points to an array of | |
361 // Representations of the same length of the numbers of parameters to the | |
362 // stub, or if NULL (the default value), Representation of each parameter | |
363 // assumed to be Tagged(). | |
364 SmartArrayPointer<Representation> register_param_representations_; | |
365 | 405 |
366 Address deoptimization_handler_; | 406 Address deoptimization_handler_; |
367 HandlerArgumentsMode handler_arguments_mode_; | 407 HandlerArgumentsMode handler_arguments_mode_; |
368 | 408 |
369 ExternalReference miss_handler_; | 409 ExternalReference miss_handler_; |
370 bool has_miss_handler_; | 410 bool has_miss_handler_; |
371 DISALLOW_COPY_AND_ASSIGN(CodeStubInterfaceDescriptor); | |
372 }; | 411 }; |
373 | 412 |
374 | 413 |
375 class PlatformCallInterfaceDescriptor; | 414 class CallInterfaceDescriptor: public InterfaceDescriptor { |
376 | |
377 | |
378 class CallInterfaceDescriptor { | |
379 public: | 415 public: |
380 CallInterfaceDescriptor() | 416 CallInterfaceDescriptor() { } |
381 : register_param_count_(-1), | |
382 register_params_(NULL), | |
383 param_representations_(NULL), | |
384 platform_specific_descriptor_(NULL) { } | |
385 | 417 |
386 // A copy of the passed in registers and param_representations is made | 418 // A copy of the passed in registers and param_representations is made |
387 // and owned by the CallInterfaceDescriptor. | 419 // and owned by the CallInterfaceDescriptor. |
388 | 420 |
389 // TODO(mvstanton): Instead of taking parallel arrays register and | 421 // TODO(mvstanton): Instead of taking parallel arrays register and |
390 // param_representations, how about a struct that puts the representation | 422 // param_representations, how about a struct that puts the representation |
391 // and register side by side (eg, RegRep(r1, Representation::Tagged()). | 423 // and register side by side (eg, RegRep(r1, Representation::Tagged()). |
392 // The same should go for the CodeStubInterfaceDescriptor class. | 424 // The same should go for the CodeStubInterfaceDescriptor class. |
393 void Initialize(int register_parameter_count, Register* registers, | 425 void Initialize(int register_parameter_count, Register* registers, |
394 Representation* param_representations, | 426 Representation* param_representations, |
395 PlatformCallInterfaceDescriptor* platform_descriptor = NULL); | 427 PlatformInterfaceDescriptor* platform_descriptor = NULL); |
396 | |
397 bool initialized() const { return register_param_count_ >= 0; } | |
398 | |
399 int environment_length() const { | |
400 return register_param_count_; | |
401 } | |
402 | |
403 Representation GetParameterRepresentation(int index) const { | |
404 return param_representations_[index]; | |
405 } | |
406 | |
407 Register GetParameterRegister(int index) const { | |
408 return register_params_[index]; | |
409 } | |
410 | |
411 PlatformCallInterfaceDescriptor* platform_specific_descriptor() const { | |
412 return platform_specific_descriptor_; | |
413 } | |
414 | |
415 private: | |
416 int register_param_count_; | |
417 SmartArrayPointer<Register> register_params_; | |
418 SmartArrayPointer<Representation> param_representations_; | |
419 PlatformCallInterfaceDescriptor* platform_specific_descriptor_; | |
420 }; | 428 }; |
421 | 429 |
422 | 430 |
423 class HydrogenCodeStub : public CodeStub { | 431 class HydrogenCodeStub : public CodeStub { |
424 public: | 432 public: |
425 enum InitializationState { | 433 enum InitializationState { |
426 UNINITIALIZED, | 434 UNINITIALIZED, |
427 INITIALIZED | 435 INITIALIZED |
428 }; | 436 }; |
429 | 437 |
(...skipping 2110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 | 2548 |
2541 | 2549 |
2542 class CallDescriptors { | 2550 class CallDescriptors { |
2543 public: | 2551 public: |
2544 static void InitializeForIsolate(Isolate* isolate); | 2552 static void InitializeForIsolate(Isolate* isolate); |
2545 }; | 2553 }; |
2546 | 2554 |
2547 } } // namespace v8::internal | 2555 } } // namespace v8::internal |
2548 | 2556 |
2549 #endif // V8_CODE_STUBS_H_ | 2557 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |