OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 } | 379 } |
380 } | 380 } |
381 } | 381 } |
382 | 382 |
383 // Invoke the platform-dependent code generator to do the actual | 383 // Invoke the platform-dependent code generator to do the actual |
384 // declaration the global variables and functions. | 384 // declaration the global variables and functions. |
385 DeclareGlobals(array); | 385 DeclareGlobals(array); |
386 } | 386 } |
387 | 387 |
388 | 388 |
389 struct InlineRuntimeLUT { | 389 |
390 void (CodeGenerator::*method)(ZoneList<Expression*>*); | 390 // Special cases: These 'runtime calls' manipulate the current |
391 const char* name; | 391 // frame and are only used 1 or two places, so we generate them |
| 392 // inline instead of generating calls to them. They are used |
| 393 // for implementing Function.prototype.call() and |
| 394 // Function.prototype.apply(). |
| 395 CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = { |
| 396 {&CodeGenerator::GenerateIsSmi, "_IsSmi"}, |
| 397 {&CodeGenerator::GenerateIsNonNegativeSmi, "_IsNonNegativeSmi"}, |
| 398 {&CodeGenerator::GenerateIsArray, "_IsArray"}, |
| 399 {&CodeGenerator::GenerateArgumentsLength, "_ArgumentsLength"}, |
| 400 {&CodeGenerator::GenerateArgumentsAccess, "_Arguments"}, |
| 401 {&CodeGenerator::GenerateValueOf, "_ValueOf"}, |
| 402 {&CodeGenerator::GenerateSetValueOf, "_SetValueOf"}, |
| 403 {&CodeGenerator::GenerateFastCharCodeAt, "_FastCharCodeAt"}, |
| 404 {&CodeGenerator::GenerateObjectEquals, "_ObjectEquals"}, |
| 405 {&CodeGenerator::GenerateLog, "_Log"} |
392 }; | 406 }; |
393 | 407 |
394 | 408 |
| 409 CodeGenerator::InlineRuntimeLUT* CodeGenerator::FindInlineRuntimeLUT( |
| 410 Handle<String> name) { |
| 411 const int entries_count = |
| 412 sizeof(kInlineRuntimeLUT) / sizeof(InlineRuntimeLUT); |
| 413 for (int i = 0; i < entries_count; i++) { |
| 414 InlineRuntimeLUT* entry = &kInlineRuntimeLUT[i]; |
| 415 if (name->IsEqualTo(CStrVector(entry->name))) { |
| 416 return entry; |
| 417 } |
| 418 } |
| 419 return NULL; |
| 420 } |
| 421 |
| 422 |
395 bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) { | 423 bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) { |
396 ZoneList<Expression*>* args = node->arguments(); | 424 ZoneList<Expression*>* args = node->arguments(); |
397 // Special cases: These 'runtime calls' manipulate the current | |
398 // frame and are only used 1 or two places, so we generate them | |
399 // inline instead of generating calls to them. They are used | |
400 // for implementing Function.prototype.call() and | |
401 // Function.prototype.apply(). | |
402 static const InlineRuntimeLUT kInlineRuntimeLUT[] = { | |
403 {&v8::internal::CodeGenerator::GenerateIsSmi, | |
404 "_IsSmi"}, | |
405 {&v8::internal::CodeGenerator::GenerateIsNonNegativeSmi, | |
406 "_IsNonNegativeSmi"}, | |
407 {&v8::internal::CodeGenerator::GenerateIsArray, | |
408 "_IsArray"}, | |
409 {&v8::internal::CodeGenerator::GenerateArgumentsLength, | |
410 "_ArgumentsLength"}, | |
411 {&v8::internal::CodeGenerator::GenerateArgumentsAccess, | |
412 "_Arguments"}, | |
413 {&v8::internal::CodeGenerator::GenerateValueOf, | |
414 "_ValueOf"}, | |
415 {&v8::internal::CodeGenerator::GenerateSetValueOf, | |
416 "_SetValueOf"}, | |
417 {&v8::internal::CodeGenerator::GenerateFastCharCodeAt, | |
418 "_FastCharCodeAt"}, | |
419 {&v8::internal::CodeGenerator::GenerateObjectEquals, | |
420 "_ObjectEquals"}, | |
421 {&v8::internal::CodeGenerator::GenerateLog, | |
422 "_Log"} | |
423 }; | |
424 Handle<String> name = node->name(); | 425 Handle<String> name = node->name(); |
425 if (name->length() > 0 && name->Get(0) == '_') { | 426 if (name->length() > 0 && name->Get(0) == '_') { |
426 for (unsigned i = 0; | 427 InlineRuntimeLUT* entry = FindInlineRuntimeLUT(name); |
427 i < sizeof(kInlineRuntimeLUT) / sizeof(InlineRuntimeLUT); | 428 if (entry != NULL) { |
428 i++) { | 429 ((*this).*(entry->method))(args); |
429 const InlineRuntimeLUT* entry = kInlineRuntimeLUT + i; | 430 return true; |
430 if (name->IsEqualTo(CStrVector(entry->name))) { | |
431 ((*this).*(entry->method))(args); | |
432 return true; | |
433 } | |
434 } | 431 } |
435 } | 432 } |
436 return false; | 433 return false; |
437 } | 434 } |
438 | 435 |
439 | 436 |
| 437 bool CodeGenerator::PatchInlineRuntimeEntry(Handle<String> name, |
| 438 const CodeGenerator::InlineRuntimeLUT& new_entry, |
| 439 CodeGenerator::InlineRuntimeLUT* old_entry) { |
| 440 InlineRuntimeLUT* entry = FindInlineRuntimeLUT(name); |
| 441 if (entry == NULL) return false; |
| 442 if (old_entry != NULL) { |
| 443 old_entry->name = entry->name; |
| 444 old_entry->method = entry->method; |
| 445 } |
| 446 entry->name = new_entry.name; |
| 447 entry->method = new_entry.method; |
| 448 return true; |
| 449 } |
| 450 |
| 451 |
440 void CodeGenerator::GenerateFastCaseSwitchStatement(SwitchStatement* node, | 452 void CodeGenerator::GenerateFastCaseSwitchStatement(SwitchStatement* node, |
441 int min_index, | 453 int min_index, |
442 int range, | 454 int range, |
443 int default_index) { | 455 int default_index) { |
444 ZoneList<CaseClause*>* cases = node->cases(); | 456 ZoneList<CaseClause*>* cases = node->cases(); |
445 int length = cases->length(); | 457 int length = cases->length(); |
446 | 458 |
447 // Label pointer per number in range. | 459 // Label pointer per number in range. |
448 SmartPointer<Label*> case_targets(NewArray<Label*>(range)); | 460 SmartPointer<Label*> case_targets(NewArray<Label*>(range)); |
449 | 461 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 void ArgumentsAccessStub::Generate(MacroAssembler* masm) { | 627 void ArgumentsAccessStub::Generate(MacroAssembler* masm) { |
616 switch (type_) { | 628 switch (type_) { |
617 case READ_LENGTH: GenerateReadLength(masm); break; | 629 case READ_LENGTH: GenerateReadLength(masm); break; |
618 case READ_ELEMENT: GenerateReadElement(masm); break; | 630 case READ_ELEMENT: GenerateReadElement(masm); break; |
619 case NEW_OBJECT: GenerateNewObject(masm); break; | 631 case NEW_OBJECT: GenerateNewObject(masm); break; |
620 } | 632 } |
621 } | 633 } |
622 | 634 |
623 | 635 |
624 } } // namespace v8::internal | 636 } } // namespace v8::internal |
OLD | NEW |