| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 explicit FullCodeGenerator(MacroAssembler* masm) | 80 explicit FullCodeGenerator(MacroAssembler* masm) |
| 81 : masm_(masm), | 81 : masm_(masm), |
| 82 info_(NULL), | 82 info_(NULL), |
| 83 scope_(NULL), | 83 scope_(NULL), |
| 84 nesting_stack_(NULL), | 84 nesting_stack_(NULL), |
| 85 loop_depth_(0), | 85 loop_depth_(0), |
| 86 context_(NULL), | 86 context_(NULL), |
| 87 bailout_entries_(0), | 87 bailout_entries_(0), |
| 88 stack_checks_(2), // There's always at least one. | 88 stack_checks_(2) { // There's always at least one. |
| 89 forward_bailout_stack_(NULL), | |
| 90 forward_bailout_pending_(NULL) { | |
| 91 } | 89 } |
| 92 | 90 |
| 93 static bool MakeCode(CompilationInfo* info); | 91 static bool MakeCode(CompilationInfo* info); |
| 94 | 92 |
| 95 void Generate(CompilationInfo* info); | 93 void Generate(CompilationInfo* info); |
| 96 void PopulateDeoptimizationData(Handle<Code> code); | 94 void PopulateDeoptimizationData(Handle<Code> code); |
| 97 | 95 |
| 98 class StateField : public BitField<State, 0, 8> { }; | 96 class StateField : public BitField<State, 0, 8> { }; |
| 99 class PcField : public BitField<unsigned, 8, 32-8> { }; | 97 class PcField : public BitField<unsigned, 8, 32-8> { }; |
| 100 | 98 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 : NestedStatement(codegen) { | 266 : NestedStatement(codegen) { |
| 269 } | 267 } |
| 270 virtual ~WithOrCatch() {} | 268 virtual ~WithOrCatch() {} |
| 271 | 269 |
| 272 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 270 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
| 273 ++(*context_length); | 271 ++(*context_length); |
| 274 return previous_; | 272 return previous_; |
| 275 } | 273 } |
| 276 }; | 274 }; |
| 277 | 275 |
| 278 // The forward bailout stack keeps track of the expressions that can | |
| 279 // bail out to just before the control flow is split in a child | |
| 280 // node. The stack elements are linked together through the parent | |
| 281 // link when visiting expressions in test contexts after requesting | |
| 282 // bailout in child forwarding. | |
| 283 class ForwardBailoutStack BASE_EMBEDDED { | |
| 284 public: | |
| 285 ForwardBailoutStack(Expression* expr, ForwardBailoutStack* parent) | |
| 286 : expr_(expr), parent_(parent) { } | |
| 287 | |
| 288 Expression* expr() const { return expr_; } | |
| 289 ForwardBailoutStack* parent() const { return parent_; } | |
| 290 | |
| 291 private: | |
| 292 Expression* const expr_; | |
| 293 ForwardBailoutStack* const parent_; | |
| 294 }; | |
| 295 | |
| 296 // Type of a member function that generates inline code for a native function. | 276 // Type of a member function that generates inline code for a native function. |
| 297 typedef void (FullCodeGenerator::*InlineFunctionGenerator) | 277 typedef void (FullCodeGenerator::*InlineFunctionGenerator)(CallRuntime* expr); |
| 298 (ZoneList<Expression*>*); | |
| 299 | 278 |
| 300 static const InlineFunctionGenerator kInlineFunctionGenerators[]; | 279 static const InlineFunctionGenerator kInlineFunctionGenerators[]; |
| 301 | 280 |
| 302 // A platform-specific utility to overwrite the accumulator register | 281 // A platform-specific utility to overwrite the accumulator register |
| 303 // with a GC-safe value. | 282 // with a GC-safe value. |
| 304 void ClearAccumulator(); | 283 void ClearAccumulator(); |
| 305 | 284 |
| 306 // Determine whether or not to inline the smi case for the given | 285 // Determine whether or not to inline the smi case for the given |
| 307 // operation. | 286 // operation. |
| 308 bool ShouldInlineSmiCase(Token::Value op); | 287 bool ShouldInlineSmiCase(Token::Value op); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 // An operand used to read/write a stack-allocated (PARAMETER or LOCAL) | 328 // An operand used to read/write a stack-allocated (PARAMETER or LOCAL) |
| 350 // variable. Writing does not need the write barrier. | 329 // variable. Writing does not need the write barrier. |
| 351 MemOperand StackOperand(Variable* var); | 330 MemOperand StackOperand(Variable* var); |
| 352 | 331 |
| 353 // An operand used to read/write a known (PARAMETER, LOCAL, or CONTEXT) | 332 // An operand used to read/write a known (PARAMETER, LOCAL, or CONTEXT) |
| 354 // variable. May emit code to traverse the context chain, loading the | 333 // variable. May emit code to traverse the context chain, loading the |
| 355 // found context into the scratch register. Writing to this operand will | 334 // found context into the scratch register. Writing to this operand will |
| 356 // need the write barrier if location is CONTEXT. | 335 // need the write barrier if location is CONTEXT. |
| 357 MemOperand VarOperand(Variable* var, Register scratch); | 336 MemOperand VarOperand(Variable* var, Register scratch); |
| 358 | 337 |
| 359 // Forward the bailout responsibility for the given expression to | |
| 360 // the next child visited (which must be in a test context). | |
| 361 void ForwardBailoutToChild(Expression* expr); | |
| 362 | |
| 363 void VisitForEffect(Expression* expr) { | 338 void VisitForEffect(Expression* expr) { |
| 364 EffectContext context(this); | 339 EffectContext context(this); |
| 365 VisitInCurrentContext(expr); | 340 Visit(expr); |
| 341 PrepareForBailout(expr, NO_REGISTERS); |
| 366 } | 342 } |
| 367 | 343 |
| 368 void VisitForAccumulatorValue(Expression* expr) { | 344 void VisitForAccumulatorValue(Expression* expr) { |
| 369 AccumulatorValueContext context(this); | 345 AccumulatorValueContext context(this); |
| 370 VisitInCurrentContext(expr); | 346 Visit(expr); |
| 347 PrepareForBailout(expr, TOS_REG); |
| 371 } | 348 } |
| 372 | 349 |
| 373 void VisitForStackValue(Expression* expr) { | 350 void VisitForStackValue(Expression* expr) { |
| 374 StackValueContext context(this); | 351 StackValueContext context(this); |
| 375 VisitInCurrentContext(expr); | 352 Visit(expr); |
| 353 PrepareForBailout(expr, NO_REGISTERS); |
| 376 } | 354 } |
| 377 | 355 |
| 378 void VisitForControl(Expression* expr, | 356 void VisitForControl(Expression* expr, |
| 379 Label* if_true, | 357 Label* if_true, |
| 380 Label* if_false, | 358 Label* if_false, |
| 381 Label* fall_through) { | 359 Label* fall_through) { |
| 382 TestContext context(this, expr, if_true, if_false, fall_through); | 360 TestContext context(this, expr, if_true, if_false, fall_through); |
| 383 VisitInCurrentContext(expr); | 361 Visit(expr); |
| 362 // For test contexts, we prepare for bailout before branching, not at |
| 363 // the end of the entire expression. This happens as part of visiting |
| 364 // the expression. |
| 384 } | 365 } |
| 385 | 366 |
| 367 void VisitInDuplicateContext(Expression* expr); |
| 368 |
| 386 void VisitDeclarations(ZoneList<Declaration*>* declarations); | 369 void VisitDeclarations(ZoneList<Declaration*>* declarations); |
| 387 void DeclareGlobals(Handle<FixedArray> pairs); | 370 void DeclareGlobals(Handle<FixedArray> pairs); |
| 388 int DeclareGlobalsFlags(); | 371 int DeclareGlobalsFlags(); |
| 389 | 372 |
| 390 // Try to perform a comparison as a fast inlined literal compare if | 373 // Try to perform a comparison as a fast inlined literal compare if |
| 391 // the operands allow it. Returns true if the compare operations | 374 // the operands allow it. Returns true if the compare operations |
| 392 // has been matched and all code generated; false otherwise. | 375 // has been matched and all code generated; false otherwise. |
| 393 bool TryLiteralCompare(CompareOperation* compare); | 376 bool TryLiteralCompare(CompareOperation* compare); |
| 394 | 377 |
| 395 // Platform-specific code for comparing the type of a value with | 378 // Platform-specific code for comparing the type of a value with |
| 396 // a given literal string. | 379 // a given literal string. |
| 397 void EmitLiteralCompareTypeof(Expression* expr, Handle<String> check); | 380 void EmitLiteralCompareTypeof(Expression* expr, |
| 381 Expression* sub_expr, |
| 382 Handle<String> check); |
| 398 | 383 |
| 399 // Platform-specific code for equality comparison with a nil-like value. | 384 // Platform-specific code for equality comparison with a nil-like value. |
| 400 void EmitLiteralCompareNil(CompareOperation* expr, | 385 void EmitLiteralCompareNil(CompareOperation* expr, |
| 401 Expression* sub_expr, | 386 Expression* sub_expr, |
| 402 NilValue nil); | 387 NilValue nil); |
| 403 | 388 |
| 404 // Bailout support. | 389 // Bailout support. |
| 405 void PrepareForBailout(Expression* node, State state); | 390 void PrepareForBailout(Expression* node, State state); |
| 406 void PrepareForBailoutForId(int id, State state); | 391 void PrepareForBailoutForId(int id, State state); |
| 407 | 392 |
| 408 // Record a call's return site offset, used to rebuild the frame if the | 393 // Record a call's return site offset, used to rebuild the frame if the |
| 409 // called function was inlined at the site. | 394 // called function was inlined at the site. |
| 410 void RecordJSReturnSite(Call* call); | 395 void RecordJSReturnSite(Call* call); |
| 411 | 396 |
| 412 // Prepare for bailout before a test (or compare) and branch. If | 397 // Prepare for bailout before a test (or compare) and branch. If |
| 413 // should_normalize, then the following comparison will not handle the | 398 // should_normalize, then the following comparison will not handle the |
| 414 // canonical JS true value so we will insert a (dead) test against true at | 399 // canonical JS true value so we will insert a (dead) test against true at |
| 415 // the actual bailout target from the optimized code. If not | 400 // the actual bailout target from the optimized code. If not |
| 416 // should_normalize, the true and false labels are ignored. | 401 // should_normalize, the true and false labels are ignored. |
| 417 void PrepareForBailoutBeforeSplit(State state, | 402 void PrepareForBailoutBeforeSplit(Expression* expr, |
| 418 bool should_normalize, | 403 bool should_normalize, |
| 419 Label* if_true, | 404 Label* if_true, |
| 420 Label* if_false); | 405 Label* if_false); |
| 421 | 406 |
| 422 // Platform-specific code for a variable, constant, or function | 407 // Platform-specific code for a variable, constant, or function |
| 423 // declaration. Functions have an initial value. | 408 // declaration. Functions have an initial value. |
| 424 void EmitDeclaration(VariableProxy* proxy, | 409 void EmitDeclaration(VariableProxy* proxy, |
| 425 VariableMode mode, | 410 VariableMode mode, |
| 426 FunctionLiteral* function, | 411 FunctionLiteral* function, |
| 427 int* global_count); | 412 int* global_count); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 442 void EmitCallWithStub(Call* expr, CallFunctionFlags flags); | 427 void EmitCallWithStub(Call* expr, CallFunctionFlags flags); |
| 443 void EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode); | 428 void EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode); |
| 444 void EmitKeyedCallWithIC(Call* expr, Expression* key); | 429 void EmitKeyedCallWithIC(Call* expr, Expression* key); |
| 445 | 430 |
| 446 // Platform-specific code for inline runtime calls. | 431 // Platform-specific code for inline runtime calls. |
| 447 InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id); | 432 InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id); |
| 448 | 433 |
| 449 void EmitInlineRuntimeCall(CallRuntime* expr); | 434 void EmitInlineRuntimeCall(CallRuntime* expr); |
| 450 | 435 |
| 451 #define EMIT_INLINE_RUNTIME_CALL(name, x, y) \ | 436 #define EMIT_INLINE_RUNTIME_CALL(name, x, y) \ |
| 452 void Emit##name(ZoneList<Expression*>* arguments); | 437 void Emit##name(CallRuntime* expr); |
| 453 INLINE_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL) | 438 INLINE_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL) |
| 454 INLINE_RUNTIME_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL) | 439 INLINE_RUNTIME_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL) |
| 455 #undef EMIT_INLINE_RUNTIME_CALL | 440 #undef EMIT_INLINE_RUNTIME_CALL |
| 456 | 441 |
| 457 // Platform-specific code for loading variables. | 442 // Platform-specific code for loading variables. |
| 458 void EmitLoadGlobalCheckExtensions(Variable* var, | 443 void EmitLoadGlobalCheckExtensions(Variable* var, |
| 459 TypeofState typeof_state, | 444 TypeofState typeof_state, |
| 460 Label* slow); | 445 Label* slow); |
| 461 MemOperand ContextSlotOperandCheckExtensions(Variable* var, Label* slow); | 446 MemOperand ContextSlotOperandCheckExtensions(Variable* var, Label* slow); |
| 462 void EmitDynamicLookupFastCase(Variable* var, | 447 void EmitDynamicLookupFastCase(Variable* var, |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 // AST node visit functions. | 554 // AST node visit functions. |
| 570 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | 555 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); |
| 571 AST_NODE_LIST(DECLARE_VISIT) | 556 AST_NODE_LIST(DECLARE_VISIT) |
| 572 #undef DECLARE_VISIT | 557 #undef DECLARE_VISIT |
| 573 | 558 |
| 574 void EmitUnaryOperation(UnaryOperation* expr, const char* comment); | 559 void EmitUnaryOperation(UnaryOperation* expr, const char* comment); |
| 575 | 560 |
| 576 void VisitComma(BinaryOperation* expr); | 561 void VisitComma(BinaryOperation* expr); |
| 577 void VisitLogicalExpression(BinaryOperation* expr); | 562 void VisitLogicalExpression(BinaryOperation* expr); |
| 578 void VisitArithmeticExpression(BinaryOperation* expr); | 563 void VisitArithmeticExpression(BinaryOperation* expr); |
| 579 void VisitInCurrentContext(Expression* expr); | |
| 580 | 564 |
| 581 void VisitForTypeofValue(Expression* expr); | 565 void VisitForTypeofValue(Expression* expr); |
| 582 | 566 |
| 583 struct BailoutEntry { | 567 struct BailoutEntry { |
| 584 unsigned id; | 568 unsigned id; |
| 585 unsigned pc_and_state; | 569 unsigned pc_and_state; |
| 586 }; | 570 }; |
| 587 | 571 |
| 588 | 572 |
| 589 class ExpressionContext BASE_EMBEDDED { | 573 class ExpressionContext BASE_EMBEDDED { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 | 748 |
| 765 MacroAssembler* masm_; | 749 MacroAssembler* masm_; |
| 766 CompilationInfo* info_; | 750 CompilationInfo* info_; |
| 767 Scope* scope_; | 751 Scope* scope_; |
| 768 Label return_label_; | 752 Label return_label_; |
| 769 NestedStatement* nesting_stack_; | 753 NestedStatement* nesting_stack_; |
| 770 int loop_depth_; | 754 int loop_depth_; |
| 771 const ExpressionContext* context_; | 755 const ExpressionContext* context_; |
| 772 ZoneList<BailoutEntry> bailout_entries_; | 756 ZoneList<BailoutEntry> bailout_entries_; |
| 773 ZoneList<BailoutEntry> stack_checks_; | 757 ZoneList<BailoutEntry> stack_checks_; |
| 774 ForwardBailoutStack* forward_bailout_stack_; | |
| 775 ForwardBailoutStack* forward_bailout_pending_; | |
| 776 | 758 |
| 777 friend class NestedStatement; | 759 friend class NestedStatement; |
| 778 | 760 |
| 779 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 761 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
| 780 }; | 762 }; |
| 781 | 763 |
| 782 | 764 |
| 783 } } // namespace v8::internal | 765 } } // namespace v8::internal |
| 784 | 766 |
| 785 #endif // V8_FULL_CODEGEN_H_ | 767 #endif // V8_FULL_CODEGEN_H_ |
| OLD | NEW |