Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: src/fast-codegen.cc

Issue 553149: Implement simple fast-path code for functions containing this property stores and global variables. (Closed)
Patch Set: Incorporated codereview comments. Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/fast-codegen.h ('k') | src/full-codegen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "codegen-inl.h"
30 #include "data-flow.h" 31 #include "data-flow.h"
31 #include "fast-codegen.h" 32 #include "fast-codegen.h"
33 #include "full-codegen.h"
32 #include "scopes.h" 34 #include "scopes.h"
33 35
34 namespace v8 { 36 namespace v8 {
35 namespace internal { 37 namespace internal {
36 38
37 #define BAILOUT(reason) \ 39 #define BAILOUT(reason) \
38 do { \ 40 do { \
39 if (FLAG_trace_bailout) { \ 41 if (FLAG_trace_bailout) { \
40 PrintF("%s\n", reason); \ 42 PrintF("%s\n", reason); \
41 } \ 43 } \
42 has_supported_syntax_ = false; \ 44 has_supported_syntax_ = false; \
43 return; \ 45 return; \
44 } while (false) 46 } while (false)
45 47
46 48
47 #define CHECK_BAILOUT \ 49 #define CHECK_BAILOUT \
48 do { \ 50 do { \
49 if (!has_supported_syntax_) return; \ 51 if (!has_supported_syntax_) return; \
50 } while (false) 52 } while (false)
51 53
52 54
53 void FastCodeGenSyntaxChecker::Check(FunctionLiteral* fun, 55 void FastCodeGenSyntaxChecker::Check(FunctionLiteral* fun,
54 CompilationInfo* info) { 56 CompilationInfo* info) {
55 info_ = info; 57 info_ = info;
56 58
57 // We do not specialize if we do not have a receiver. 59 // We do not specialize if we do not have a receiver or if it is not a
60 // JS object with fast mode properties.
58 if (!info->has_receiver()) BAILOUT("No receiver"); 61 if (!info->has_receiver()) BAILOUT("No receiver");
62 if (!info->receiver()->IsJSObject()) BAILOUT("Receiver is not an object");
63 Handle<JSObject> object = Handle<JSObject>::cast(info->receiver());
64 if (!object->HasFastProperties()) BAILOUT("Receiver is in dictionary mode");
59 65
60 // We do not support stack or heap slots (both of which require 66 // We do not support stack or heap slots (both of which require
61 // allocation). 67 // allocation).
62 Scope* scope = fun->scope(); 68 Scope* scope = fun->scope();
63 if (scope->num_stack_slots() > 0) { 69 if (scope->num_stack_slots() > 0) {
64 BAILOUT("Function has stack-allocated locals"); 70 BAILOUT("Function has stack-allocated locals");
65 } 71 }
66 if (scope->num_heap_slots() > 0) { 72 if (scope->num_heap_slots() > 0) {
67 BAILOUT("Function has context-allocated locals"); 73 BAILOUT("Function has context-allocated locals");
68 } 74 }
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 324
319 325
320 void FastCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) { 326 void FastCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
321 BAILOUT("ThisFunction"); 327 BAILOUT("ThisFunction");
322 } 328 }
323 329
324 #undef BAILOUT 330 #undef BAILOUT
325 #undef CHECK_BAILOUT 331 #undef CHECK_BAILOUT
326 332
327 333
328 void FastCodeGenerator::MakeCode(FunctionLiteral* fun, 334 #define __ ACCESS_MASM(masm())
329 Handle<Script> script, 335
330 bool is_eval, 336 Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun,
331 CompilationInfo* info) { 337 Handle<Script> script,
338 bool is_eval,
339 CompilationInfo* info) {
340 // Label the AST before calling MakeCodePrologue, so AST node numbers are
341 // printed with the AST.
332 AstLabeler labeler; 342 AstLabeler labeler;
333 FastCodeGenerator cgen(script, is_eval);
334 labeler.Label(fun); 343 labeler.Label(fun);
335 cgen.Generate(fun, info); 344 info->set_has_this_properties(labeler.has_this_properties());
345
346 CodeGenerator::MakeCodePrologue(fun);
347
348 const int kInitialBufferSize = 4 * KB;
349 MacroAssembler masm(NULL, kInitialBufferSize);
350
351 // Generate the fast-path code.
352 FastCodeGenerator fast_cgen(&masm, script, is_eval);
353 fast_cgen.Generate(fun, info);
354 if (fast_cgen.HasStackOverflow()) {
355 ASSERT(!Top::has_pending_exception());
356 return Handle<Code>::null();
357 }
358
359 // Generate the full code for the function in bailout mode, using the same
360 // macro assembler.
361 FullCodeGenerator full_cgen(&masm, script, is_eval);
362 full_cgen.Generate(fun, FullCodeGenerator::SECONDARY);
363 if (full_cgen.HasStackOverflow()) {
364 ASSERT(!Top::has_pending_exception());
365 return Handle<Code>::null();
366 }
367
368 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
369 return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script);
336 } 370 }
337 371
338 372
339 void FastCodeGenerator::Generate(FunctionLiteral* fun, CompilationInfo* info) {
340 ASSERT(function_ == NULL);
341 ASSERT(info_ == NULL);
342 function_ = fun;
343 info_ = info;
344 VisitStatements(fun->body());
345 function_ = NULL;
346 info_ = NULL;
347 }
348
349
350 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { 373 void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
351 UNREACHABLE(); 374 UNREACHABLE();
352 } 375 }
353 376
354 377
355 void FastCodeGenerator::VisitBlock(Block* stmt) { 378 void FastCodeGenerator::VisitBlock(Block* stmt) {
356 VisitStatements(stmt->statements()); 379 VisitStatements(stmt->statements());
357 } 380 }
358 381
359 382
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 UNREACHABLE(); 475 UNREACHABLE();
453 } 476 }
454 477
455 478
456 void FastCodeGenerator::VisitSlot(Slot* expr) { 479 void FastCodeGenerator::VisitSlot(Slot* expr) {
457 UNREACHABLE(); 480 UNREACHABLE();
458 } 481 }
459 482
460 483
461 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 484 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
485 ASSERT(expr->var()->is_global() && !expr->var()->is_this());
486 Comment cmnt(masm(), ";; Global");
462 if (FLAG_print_ir) { 487 if (FLAG_print_ir) {
463 ASSERT(expr->var()->is_global() && !expr->var()->is_this());
464 SmartPointer<char> name = expr->name()->ToCString(); 488 SmartPointer<char> name = expr->name()->ToCString();
465 PrintF("%d: t%d = Global(%s)\n", expr->num(), expr->num(), *name); 489 PrintF("%d: t%d = Global(%s)\n", expr->num(), expr->num(), *name);
466 } 490 }
491 EmitGlobalVariableLoad(expr->name());
467 } 492 }
468 493
469 494
470 void FastCodeGenerator::VisitLiteral(Literal* expr) { 495 void FastCodeGenerator::VisitLiteral(Literal* expr) {
471 UNREACHABLE(); 496 UNREACHABLE();
472 } 497 }
473 498
474 499
475 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 500 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
476 UNREACHABLE(); 501 UNREACHABLE();
(...skipping 12 matching lines...) Expand all
489 514
490 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 515 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
491 UNREACHABLE(); 516 UNREACHABLE();
492 } 517 }
493 518
494 519
495 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 520 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
496 // Known to be a simple this property assignment. 521 // Known to be a simple this property assignment.
497 Visit(expr->value()); 522 Visit(expr->value());
498 523
524 Property* prop = expr->target()->AsProperty();
525 ASSERT_NOT_NULL(prop);
526 ASSERT_NOT_NULL(prop->obj()->AsVariableProxy());
527 ASSERT(prop->obj()->AsVariableProxy()->var()->is_this());
528 ASSERT(prop->key()->IsPropertyName());
529 Handle<String> name =
530 Handle<String>::cast(prop->key()->AsLiteral()->handle());
531
532 Comment cmnt(masm(), ";; Store(this)");
499 if (FLAG_print_ir) { 533 if (FLAG_print_ir) {
500 Property* prop = expr->target()->AsProperty(); 534 SmartPointer<char> name_string = name->ToCString();
501 ASSERT_NOT_NULL(prop);
502 ASSERT_NOT_NULL(prop->obj()->AsVariableProxy());
503 ASSERT(prop->obj()->AsVariableProxy()->var()->is_this());
504 ASSERT(prop->key()->IsPropertyName());
505 Handle<String> key =
506 Handle<String>::cast(prop->key()->AsLiteral()->handle());
507 SmartPointer<char> name = key->ToCString();
508 PrintF("%d: t%d = Store(this, \"%s\", t%d)\n", 535 PrintF("%d: t%d = Store(this, \"%s\", t%d)\n",
509 expr->num(), expr->num(), *name, expr->value()->num()); 536 expr->num(), expr->num(), *name_string, expr->value()->num());
510 } 537 }
538
539 EmitThisPropertyStore(name);
511 } 540 }
512 541
513 542
514 void FastCodeGenerator::VisitThrow(Throw* expr) { 543 void FastCodeGenerator::VisitThrow(Throw* expr) {
515 UNREACHABLE(); 544 UNREACHABLE();
516 } 545 }
517 546
518 547
519 void FastCodeGenerator::VisitProperty(Property* expr) { 548 void FastCodeGenerator::VisitProperty(Property* expr) {
520 UNREACHABLE(); 549 UNREACHABLE();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 582
554 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 583 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
555 UNREACHABLE(); 584 UNREACHABLE();
556 } 585 }
557 586
558 587
559 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 588 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
560 UNREACHABLE(); 589 UNREACHABLE();
561 } 590 }
562 591
592 #undef __
593
594
563 } } // namespace v8::internal 595 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.h ('k') | src/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698