| 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 |