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

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

Issue 660077: NOT FOR COMMITTING: Add fast side-effect free floating point expressions. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/safe-codegen-ia32.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
(...skipping 20 matching lines...) Expand all
31 #include "codegen-inl.h" 31 #include "codegen-inl.h"
32 #include "compiler.h" 32 #include "compiler.h"
33 #include "debug.h" 33 #include "debug.h"
34 #include "ic-inl.h" 34 #include "ic-inl.h"
35 #include "jsregexp.h" 35 #include "jsregexp.h"
36 #include "parser.h" 36 #include "parser.h"
37 #include "regexp-macro-assembler.h" 37 #include "regexp-macro-assembler.h"
38 #include "regexp-stack.h" 38 #include "regexp-stack.h"
39 #include "register-allocator-inl.h" 39 #include "register-allocator-inl.h"
40 #include "runtime.h" 40 #include "runtime.h"
41 #include "safe-codegen-ia32.h"
41 #include "scopes.h" 42 #include "scopes.h"
42 #include "virtual-frame-inl.h" 43 #include "virtual-frame-inl.h"
43 44
44 namespace v8 { 45 namespace v8 {
45 namespace internal { 46 namespace internal {
46 47
47 #define __ ACCESS_MASM(masm_) 48 #define __ ACCESS_MASM(masm_)
48 49
49 // ------------------------------------------------------------------------- 50 // -------------------------------------------------------------------------
50 // Platform-specific DeferredCode functions. 51 // Platform-specific DeferredCode functions.
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 Result result = 583 Result result =
583 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF); 584 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF);
584 frame()->Push(&result); 585 frame()->Push(&result);
585 } else { 586 } else {
586 // Anything else can be handled normally. 587 // Anything else can be handled normally.
587 Load(expr); 588 Load(expr);
588 } 589 }
589 } 590 }
590 591
591 592
593 void CodeGenerator::LoadPossiblySafeExpression(Expression* expr) {
594 SafeSyntaxChecker checker;
595 if (checker.Check(expr)) {
596 __ IncrementCounter(&Counters::safe_expression_tried, 1);
597 JumpTarget unsafe;
598 JumpTarget done;
599 Result scratch = allocator_->Allocate();
600 ASSERT(scratch.is_register());
601 Result result = allocator_->Allocate();
602 ASSERT(result.is_register());
603 SafeGenerator safe_generator(masm_, &unsafe, this, &scratch, &result);
604 result = safe_generator.Generate(expr);
605 frame()->Push(&result);
606 __ IncrementCounter(&Counters::safe_expression_succeeded, 1);
607 done.Jump();
608
609 unsafe.Bind();
610 Load(expr);
611 done.Bind();
612 } else {
613 Load(expr);
614 }
615 }
616
617
592 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() { 618 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() {
593 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; 619 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION;
594 ASSERT(scope()->arguments_shadow() != NULL); 620 ASSERT(scope()->arguments_shadow() != NULL);
595 // We don't want to do lazy arguments allocation for functions that 621 // We don't want to do lazy arguments allocation for functions that
596 // have heap-allocated contexts, because it interfers with the 622 // have heap-allocated contexts, because it interfers with the
597 // uninitialized const tracking in the context objects. 623 // uninitialized const tracking in the context objects.
598 return (scope()->num_heap_slots() > 0) 624 return (scope()->num_heap_slots() > 0)
599 ? EAGER_ARGUMENTS_ALLOCATION 625 ? EAGER_ARGUMENTS_ALLOCATION
600 : LAZY_ARGUMENTS_ALLOCATION; 626 : LAZY_ARGUMENTS_ALLOCATION;
601 } 627 }
(...skipping 2313 matching lines...) Expand 10 before | Expand all | Expand 10 after
2915 CodeForStatementPosition(node); 2941 CodeForStatementPosition(node);
2916 node->target()->break_target()->Jump(); 2942 node->target()->break_target()->Jump();
2917 } 2943 }
2918 2944
2919 2945
2920 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 2946 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
2921 ASSERT(!in_spilled_code()); 2947 ASSERT(!in_spilled_code());
2922 Comment cmnt(masm_, "[ ReturnStatement"); 2948 Comment cmnt(masm_, "[ ReturnStatement");
2923 2949
2924 CodeForStatementPosition(node); 2950 CodeForStatementPosition(node);
2925 Load(node->expression()); 2951 LoadPossiblySafeExpression(node->expression());
2926 Result return_value = frame_->Pop(); 2952 Result return_value = frame_->Pop();
2927 masm()->WriteRecordedPositions(); 2953 masm()->WriteRecordedPositions();
2928 if (function_return_is_shadowed_) { 2954 if (function_return_is_shadowed_) {
2929 function_return_.Jump(&return_value); 2955 function_return_.Jump(&return_value);
2930 } else { 2956 } else {
2931 frame_->PrepareForReturn(); 2957 frame_->PrepareForReturn();
2932 if (function_return_.is_bound()) { 2958 if (function_return_.is_bound()) {
2933 // If the function return label is already bound we reuse the 2959 // If the function return label is already bound we reuse the
2934 // code by jumping to the return site. 2960 // code by jumping to the return site.
2935 function_return_.Jump(&return_value); 2961 function_return_.Jump(&return_value);
(...skipping 1802 matching lines...) Expand 10 before | Expand all | Expand 10 after
4738 Comment cmnt(masm(), "[ Variable Assignment"); 4764 Comment cmnt(masm(), "[ Variable Assignment");
4739 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 4765 Variable* var = node->target()->AsVariableProxy()->AsVariable();
4740 ASSERT(var != NULL); 4766 ASSERT(var != NULL);
4741 Slot* slot = var->slot(); 4767 Slot* slot = var->slot();
4742 ASSERT(slot != NULL); 4768 ASSERT(slot != NULL);
4743 4769
4744 // Evaluate the right-hand side. 4770 // Evaluate the right-hand side.
4745 if (node->is_compound()) { 4771 if (node->is_compound()) {
4746 Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); 4772 Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
4747 frame()->Push(&result); 4773 frame()->Push(&result);
4748 Load(node->value()); 4774 LoadPossiblySafeExpression(node->value());
4749 4775
4750 bool overwrite_value = 4776 bool overwrite_value =
4751 (node->value()->AsBinaryOperation() != NULL && 4777 (node->value()->AsBinaryOperation() != NULL &&
4752 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 4778 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
4753 GenericBinaryOperation(node->binary_op(), 4779 GenericBinaryOperation(node->binary_op(),
4754 node->type(), 4780 node->type(),
4755 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 4781 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
4756 } else { 4782 } else {
4757 Load(node->value()); 4783 LoadPossiblySafeExpression(node->value());
4758 } 4784 }
4759 4785
4760 // Perform the assignment. 4786 // Perform the assignment.
4761 if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) { 4787 if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) {
4762 CodeForSourcePosition(node->position()); 4788 CodeForSourcePosition(node->position());
4763 StoreToSlot(slot, 4789 StoreToSlot(slot,
4764 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT); 4790 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT);
4765 } 4791 }
4766 ASSERT(frame()->height() == original_height + 1); 4792 ASSERT(frame()->height() == original_height + 1);
4767 } 4793 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4815 } else if (var != NULL) { 4841 } else if (var != NULL) {
4816 // The LoadIC stub expects the object in eax. 4842 // The LoadIC stub expects the object in eax.
4817 // Freeing eax causes the code generator to load the global into it. 4843 // Freeing eax causes the code generator to load the global into it.
4818 frame_->Spill(eax); 4844 frame_->Spill(eax);
4819 LoadGlobal(); 4845 LoadGlobal();
4820 } else { 4846 } else {
4821 frame()->Dup(); 4847 frame()->Dup();
4822 } 4848 }
4823 Result value = EmitNamedLoad(name, var != NULL); 4849 Result value = EmitNamedLoad(name, var != NULL);
4824 frame()->Push(&value); 4850 frame()->Push(&value);
4825 Load(node->value()); 4851 LoadPossiblySafeExpression(node->value());
4826 4852
4827 bool overwrite_value = 4853 bool overwrite_value =
4828 (node->value()->AsBinaryOperation() != NULL && 4854 (node->value()->AsBinaryOperation() != NULL &&
4829 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 4855 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
4830 GenericBinaryOperation(node->binary_op(), 4856 GenericBinaryOperation(node->binary_op(),
4831 node->type(), 4857 node->type(),
4832 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 4858 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
4833 } else { 4859 } else {
4834 Load(node->value()); 4860 LoadPossiblySafeExpression(node->value());
4835 } 4861 }
4836 4862
4837 // Perform the assignment. It is safe to ignore constants here. 4863 // Perform the assignment. It is safe to ignore constants here.
4838 ASSERT(var == NULL || var->mode() != Variable::CONST); 4864 ASSERT(var == NULL || var->mode() != Variable::CONST);
4839 ASSERT_NE(Token::INIT_CONST, node->op()); 4865 ASSERT_NE(Token::INIT_CONST, node->op());
4840 if (is_trivial_receiver) { 4866 if (is_trivial_receiver) {
4841 Result value = frame()->Pop(); 4867 Result value = frame()->Pop();
4842 frame()->Push(prop->obj()); 4868 frame()->Push(prop->obj());
4843 frame()->Push(&value); 4869 frame()->Push(&value);
4844 } 4870 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4894 // Evaluate the key subexpression. 4920 // Evaluate the key subexpression.
4895 Load(prop->key()); 4921 Load(prop->key());
4896 4922
4897 // Evaluate the right-hand side. 4923 // Evaluate the right-hand side.
4898 if (node->is_compound()) { 4924 if (node->is_compound()) {
4899 // Duplicate receiver and key. 4925 // Duplicate receiver and key.
4900 frame()->PushElementAt(1); 4926 frame()->PushElementAt(1);
4901 frame()->PushElementAt(1); 4927 frame()->PushElementAt(1);
4902 Result value = EmitKeyedLoad(); 4928 Result value = EmitKeyedLoad();
4903 frame()->Push(&value); 4929 frame()->Push(&value);
4904 Load(node->value()); 4930 LoadPossiblySafeExpression(node->value());
4905 4931
4906 bool overwrite_value = 4932 bool overwrite_value =
4907 (node->value()->AsBinaryOperation() != NULL && 4933 (node->value()->AsBinaryOperation() != NULL &&
4908 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 4934 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
4909 GenericBinaryOperation(node->binary_op(), 4935 GenericBinaryOperation(node->binary_op(),
4910 node->type(), 4936 node->type(),
4911 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 4937 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
4912 } else { 4938 } else {
4913 Load(node->value()); 4939 LoadPossiblySafeExpression(node->value());
4914 } 4940 }
4915 4941
4916 // Perform the assignment. It is safe to ignore constants here. 4942 // Perform the assignment. It is safe to ignore constants here.
4917 ASSERT(node->op() != Token::INIT_CONST); 4943 ASSERT(node->op() != Token::INIT_CONST);
4918 CodeForSourcePosition(node->position()); 4944 CodeForSourcePosition(node->position());
4919 Result answer = EmitKeyedStore(prop->key()->type()); 4945 Result answer = EmitKeyedStore(prop->key()->type());
4920 frame()->Push(&answer); 4946 frame()->Push(&answer);
4921 4947
4922 if (node->ends_initialization_block()) { 4948 if (node->ends_initialization_block()) {
4923 // The argument to the runtime call is the extra copy of the receiver, 4949 // The argument to the runtime call is the extra copy of the receiver,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
5013 // call. Then we call the resolved function using the given 5039 // call. Then we call the resolved function using the given
5014 // arguments. 5040 // arguments.
5015 5041
5016 // Prepare the stack for the call to the resolved function. 5042 // Prepare the stack for the call to the resolved function.
5017 Load(function); 5043 Load(function);
5018 5044
5019 // Allocate a frame slot for the receiver. 5045 // Allocate a frame slot for the receiver.
5020 frame_->Push(Factory::undefined_value()); 5046 frame_->Push(Factory::undefined_value());
5021 int arg_count = args->length(); 5047 int arg_count = args->length();
5022 for (int i = 0; i < arg_count; i++) { 5048 for (int i = 0; i < arg_count; i++) {
5023 Load(args->at(i)); 5049 LoadPossiblySafeExpression(args->at(i));
5024 } 5050 }
5025 5051
5026 // Prepare the stack for the call to ResolvePossiblyDirectEval. 5052 // Prepare the stack for the call to ResolvePossiblyDirectEval.
5027 frame_->PushElementAt(arg_count + 1); 5053 frame_->PushElementAt(arg_count + 1);
5028 if (arg_count > 0) { 5054 if (arg_count > 0) {
5029 frame_->PushElementAt(arg_count); 5055 frame_->PushElementAt(arg_count);
5030 } else { 5056 } else {
5031 frame_->Push(Factory::undefined_value()); 5057 frame_->Push(Factory::undefined_value());
5032 } 5058 }
5033 5059
(...skipping 28 matching lines...) Expand all
5062 // ---------------------------------- 5088 // ----------------------------------
5063 5089
5064 // Pass the global object as the receiver and let the IC stub 5090 // Pass the global object as the receiver and let the IC stub
5065 // patch the stack to use the global proxy as 'this' in the 5091 // patch the stack to use the global proxy as 'this' in the
5066 // invoked function. 5092 // invoked function.
5067 LoadGlobal(); 5093 LoadGlobal();
5068 5094
5069 // Load the arguments. 5095 // Load the arguments.
5070 int arg_count = args->length(); 5096 int arg_count = args->length();
5071 for (int i = 0; i < arg_count; i++) { 5097 for (int i = 0; i < arg_count; i++) {
5072 Load(args->at(i)); 5098 LoadPossiblySafeExpression(args->at(i));
5073 } 5099 }
5074 5100
5075 // Push the name of the function onto the frame. 5101 // Push the name of the function onto the frame.
5076 frame_->Push(var->name()); 5102 frame_->Push(var->name());
5077 5103
5078 // Call the IC initialization code. 5104 // Call the IC initialization code.
5079 CodeForSourcePosition(node->position()); 5105 CodeForSourcePosition(node->position());
5080 Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET_CONTEXT, 5106 Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET_CONTEXT,
5081 arg_count, 5107 arg_count,
5082 loop_nesting()); 5108 loop_nesting());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5133 args->at(1)->AsVariableProxy(), 5159 args->at(1)->AsVariableProxy(),
5134 node->position()); 5160 node->position());
5135 5161
5136 } else { 5162 } else {
5137 // Push the receiver onto the frame. 5163 // Push the receiver onto the frame.
5138 Load(property->obj()); 5164 Load(property->obj());
5139 5165
5140 // Load the arguments. 5166 // Load the arguments.
5141 int arg_count = args->length(); 5167 int arg_count = args->length();
5142 for (int i = 0; i < arg_count; i++) { 5168 for (int i = 0; i < arg_count; i++) {
5143 Load(args->at(i)); 5169 LoadPossiblySafeExpression(args->at(i));
5144 } 5170 }
5145 5171
5146 // Push the name of the function onto the frame. 5172 // Push the name of the function onto the frame.
5147 frame_->Push(name); 5173 frame_->Push(name);
5148 5174
5149 // Call the IC initialization code. 5175 // Call the IC initialization code.
5150 CodeForSourcePosition(node->position()); 5176 CodeForSourcePosition(node->position());
5151 Result result = 5177 Result result =
5152 frame_->CallCallIC(RelocInfo::CODE_TARGET, arg_count, 5178 frame_->CallCallIC(RelocInfo::CODE_TARGET, arg_count,
5153 loop_nesting()); 5179 loop_nesting());
(...skipping 6126 matching lines...) Expand 10 before | Expand all | Expand 10 after
11280 11306
11281 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 11307 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
11282 // tagged as a small integer. 11308 // tagged as a small integer.
11283 __ bind(&runtime); 11309 __ bind(&runtime);
11284 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 11310 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
11285 } 11311 }
11286 11312
11287 #undef __ 11313 #undef __
11288 11314
11289 } } // namespace v8::internal 11315 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/safe-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698