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

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

Issue 2159002: Refactoring of codegen-arm.cc to use the VirtualFrame API.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 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 | « no previous file | no next file » | 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 2708 matching lines...) Expand 10 before | Expand all | Expand 10 after
2719 frame_->CallRuntime(Runtime::kNewClosure, 2); 2719 frame_->CallRuntime(Runtime::kNewClosure, 2);
2720 frame_->EmitPush(r0); 2720 frame_->EmitPush(r0);
2721 } 2721 }
2722 } 2722 }
2723 2723
2724 2724
2725 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { 2725 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
2726 #ifdef DEBUG 2726 #ifdef DEBUG
2727 int original_height = frame_->height(); 2727 int original_height = frame_->height();
2728 #endif 2728 #endif
2729 VirtualFrame::SpilledScope spilled_scope(frame_);
2730 Comment cmnt(masm_, "[ FunctionLiteral"); 2729 Comment cmnt(masm_, "[ FunctionLiteral");
2731 2730
2732 // Build the function info and instantiate it. 2731 // Build the function info and instantiate it.
2733 Handle<SharedFunctionInfo> function_info = 2732 Handle<SharedFunctionInfo> function_info =
2734 Compiler::BuildFunctionInfo(node, script(), this); 2733 Compiler::BuildFunctionInfo(node, script(), this);
2735 // Check for stack-overflow exception. 2734 // Check for stack-overflow exception.
2736 if (HasStackOverflow()) { 2735 if (HasStackOverflow()) {
2737 ASSERT(frame_->height() == original_height); 2736 ASSERT(frame_->height() == original_height);
2738 return; 2737 return;
2739 } 2738 }
2740 InstantiateFunction(function_info); 2739 InstantiateFunction(function_info);
2741 ASSERT_EQ(original_height + 1, frame_->height()); 2740 ASSERT_EQ(original_height + 1, frame_->height());
2742 } 2741 }
2743 2742
2744 2743
2745 void CodeGenerator::VisitSharedFunctionInfoLiteral( 2744 void CodeGenerator::VisitSharedFunctionInfoLiteral(
2746 SharedFunctionInfoLiteral* node) { 2745 SharedFunctionInfoLiteral* node) {
2747 #ifdef DEBUG 2746 #ifdef DEBUG
2748 int original_height = frame_->height(); 2747 int original_height = frame_->height();
2749 #endif 2748 #endif
2750 VirtualFrame::SpilledScope spilled_scope(frame_);
2751 Comment cmnt(masm_, "[ SharedFunctionInfoLiteral"); 2749 Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
2752 InstantiateFunction(node->shared_function_info()); 2750 InstantiateFunction(node->shared_function_info());
2753 ASSERT_EQ(original_height + 1, frame_->height()); 2751 ASSERT_EQ(original_height + 1, frame_->height());
2754 } 2752 }
2755 2753
2756 2754
2757 void CodeGenerator::VisitConditional(Conditional* node) { 2755 void CodeGenerator::VisitConditional(Conditional* node) {
2758 #ifdef DEBUG 2756 #ifdef DEBUG
2759 int original_height = frame_->height(); 2757 int original_height = frame_->height();
2760 #endif 2758 #endif
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after
4034 // Update the write barrier. 4032 // Update the write barrier.
4035 __ mov(r2, Operand(JSValue::kValueOffset - kHeapObjectTag)); 4033 __ mov(r2, Operand(JSValue::kValueOffset - kHeapObjectTag));
4036 __ RecordWrite(r1, r2, r3); 4034 __ RecordWrite(r1, r2, r3);
4037 // Leave. 4035 // Leave.
4038 leave.Bind(); 4036 leave.Bind();
4039 frame_->EmitPush(r0); 4037 frame_->EmitPush(r0);
4040 } 4038 }
4041 4039
4042 4040
4043 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { 4041 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
4044 VirtualFrame::SpilledScope spilled_scope(frame_);
4045 ASSERT(args->length() == 1); 4042 ASSERT(args->length() == 1);
4046 LoadAndSpill(args->at(0)); 4043 Load(args->at(0));
4047 frame_->EmitPop(r0); 4044 Register reg = frame_->PopToRegister();
4048 __ tst(r0, Operand(kSmiTagMask)); 4045 __ tst(reg, Operand(kSmiTagMask));
4049 cc_reg_ = eq; 4046 cc_reg_ = eq;
4050 } 4047 }
4051 4048
4052 4049
4053 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) { 4050 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
4054 VirtualFrame::SpilledScope spilled_scope(frame_);
4055 // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc. 4051 // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc.
4056 ASSERT_EQ(args->length(), 3); 4052 ASSERT_EQ(args->length(), 3);
4057 #ifdef ENABLE_LOGGING_AND_PROFILING 4053 #ifdef ENABLE_LOGGING_AND_PROFILING
4058 if (ShouldGenerateLog(args->at(0))) { 4054 if (ShouldGenerateLog(args->at(0))) {
4059 LoadAndSpill(args->at(1)); 4055 Load(args->at(1));
4060 LoadAndSpill(args->at(2)); 4056 Load(args->at(2));
4057 frame_->SpillAll();
4058 VirtualFrame::SpilledScope spilled_scope(frame_);
4061 __ CallRuntime(Runtime::kLog, 2); 4059 __ CallRuntime(Runtime::kLog, 2);
4062 } 4060 }
4063 #endif 4061 #endif
4064 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 4062 frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex);
4065 frame_->EmitPush(r0);
4066 } 4063 }
4067 4064
4068 4065
4069 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { 4066 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
4070 VirtualFrame::SpilledScope spilled_scope(frame_);
4071 ASSERT(args->length() == 1); 4067 ASSERT(args->length() == 1);
4072 LoadAndSpill(args->at(0)); 4068 Load(args->at(0));
4073 frame_->EmitPop(r0); 4069 Register reg = frame_->PopToRegister();
4074 __ tst(r0, Operand(kSmiTagMask | 0x80000000u)); 4070 __ tst(reg, Operand(kSmiTagMask | 0x80000000u));
4075 cc_reg_ = eq; 4071 cc_reg_ = eq;
4076 } 4072 }
4077 4073
4078 4074
4079 // Generates the Math.pow method - currently just calls runtime. 4075 // Generates the Math.pow method - currently just calls runtime.
4080 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { 4076 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
4081 ASSERT(args->length() == 2); 4077 ASSERT(args->length() == 2);
4082 Load(args->at(0)); 4078 Load(args->at(0));
4083 Load(args->at(1)); 4079 Load(args->at(1));
4084 frame_->CallRuntime(Runtime::kMath_pow, 2); 4080 frame_->CallRuntime(Runtime::kMath_pow, 2);
(...skipping 10 matching lines...) Expand all
4095 } 4091 }
4096 4092
4097 4093
4098 // This generates code that performs a charCodeAt() call or returns 4094 // This generates code that performs a charCodeAt() call or returns
4099 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt. 4095 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
4100 // It can handle flat, 8 and 16 bit characters and cons strings where the 4096 // It can handle flat, 8 and 16 bit characters and cons strings where the
4101 // answer is found in the left hand branch of the cons. The slow case will 4097 // answer is found in the left hand branch of the cons. The slow case will
4102 // flatten the string, which will ensure that the answer is in the left hand 4098 // flatten the string, which will ensure that the answer is in the left hand
4103 // side the next time around. 4099 // side the next time around.
4104 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { 4100 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
4105 VirtualFrame::SpilledScope spilled_scope(frame_);
4106 ASSERT(args->length() == 2); 4101 ASSERT(args->length() == 2);
4107 Comment(masm_, "[ GenerateFastCharCodeAt"); 4102 Comment(masm_, "[ GenerateFastCharCodeAt");
4108 4103
4109 LoadAndSpill(args->at(0)); 4104 Load(args->at(0));
4110 LoadAndSpill(args->at(1)); 4105 Load(args->at(1));
4111 frame_->EmitPop(r1); // Index. 4106 Register index = frame_->PopToRegister(); // Index.
4112 frame_->EmitPop(r2); // String. 4107 Register string = frame_->PopToRegister(index); // String.
4108 Register result = VirtualFrame::scratch0();
4109 Register scratch = VirtualFrame::scratch1();
4113 4110
4114 Label slow_case; 4111 Label slow_case;
4115 Label exit; 4112 Label exit;
4116 StringHelper::GenerateFastCharCodeAt(masm_, 4113 StringHelper::GenerateFastCharCodeAt(masm_,
4117 r2, 4114 string,
4118 r1, 4115 index,
4119 r3, 4116 scratch,
4120 r0, 4117 result,
4121 &slow_case, 4118 &slow_case,
4122 &slow_case, 4119 &slow_case,
4123 &slow_case, 4120 &slow_case,
4124 &slow_case); 4121 &slow_case);
4125 __ jmp(&exit); 4122 __ jmp(&exit);
4126 4123
4127 __ bind(&slow_case); 4124 __ bind(&slow_case);
4128 // Move the undefined value into the result register, which will 4125 // Move the undefined value into the result register, which will
4129 // trigger the slow case. 4126 // trigger the slow case.
4130 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 4127 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
4131 4128
4132 __ bind(&exit); 4129 __ bind(&exit);
4133 frame_->EmitPush(r0); 4130 frame_->EmitPush(result);
4134 } 4131 }
4135 4132
4136 4133
4137 void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) { 4134 void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) {
4138 Comment(masm_, "[ GenerateCharFromCode"); 4135 Comment(masm_, "[ GenerateCharFromCode");
4139 ASSERT(args->length() == 1); 4136 ASSERT(args->length() == 1);
4140 4137
4141 Register code = r1; 4138 Register code = r1;
4142 Register scratch = ip; 4139 Register scratch = ip;
4143 Register result = r0; 4140 Register result = r0;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
4244 __ tst(r0, Operand(kSmiTagMask)); 4241 __ tst(r0, Operand(kSmiTagMask));
4245 false_target()->Branch(eq); 4242 false_target()->Branch(eq);
4246 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 4243 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
4247 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); 4244 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
4248 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 4245 __ tst(r1, Operand(1 << Map::kIsUndetectable));
4249 cc_reg_ = ne; 4246 cc_reg_ = ne;
4250 } 4247 }
4251 4248
4252 4249
4253 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) { 4250 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
4254 VirtualFrame::SpilledScope spilled_scope(frame_);
4255 ASSERT(args->length() == 0); 4251 ASSERT(args->length() == 0);
4256 4252
4253 Register scratch0 = VirtualFrame::scratch0();
4254 Register scratch1 = VirtualFrame::scratch1();
4257 // Get the frame pointer for the calling frame. 4255 // Get the frame pointer for the calling frame.
4258 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 4256 __ ldr(scratch0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
4259 4257
4260 // Skip the arguments adaptor frame if it exists. 4258 // Skip the arguments adaptor frame if it exists.
4261 Label check_frame_marker; 4259 __ ldr(scratch1,
4262 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset)); 4260 MemOperand(scratch0, StandardFrameConstants::kContextOffset));
4263 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 4261 __ cmp(scratch1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4264 __ b(ne, &check_frame_marker); 4262 __ ldr(scratch0,
4265 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset)); 4263 MemOperand(scratch0, StandardFrameConstants::kCallerFPOffset), eq);
4266 4264
4267 // Check the marker in the calling frame. 4265 // Check the marker in the calling frame.
4268 __ bind(&check_frame_marker); 4266 __ ldr(scratch1,
4269 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); 4267 MemOperand(scratch0, StandardFrameConstants::kMarkerOffset));
4270 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 4268 __ cmp(scratch1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
4271 cc_reg_ = eq; 4269 cc_reg_ = eq;
4272 } 4270 }
4273 4271
4274 4272
4275 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 4273 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
4276 VirtualFrame::SpilledScope spilled_scope(frame_);
4277 ASSERT(args->length() == 0); 4274 ASSERT(args->length() == 0);
4278 4275
4279 Label exit; 4276 Register tos = frame_->GetTOSRegister();
4277 Register scratch0 = VirtualFrame::scratch0();
4278 Register scratch1 = VirtualFrame::scratch1();
4279
4280 // Check if the calling frame is an arguments adaptor frame.
4281 __ ldr(scratch0,
4282 MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
4283 __ ldr(scratch1,
4284 MemOperand(scratch0, StandardFrameConstants::kContextOffset));
4285 __ cmp(scratch1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4280 4286
4281 // Get the number of formal parameters. 4287 // Get the number of formal parameters.
4282 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); 4288 __ mov(tos, Operand(Smi::FromInt(scope()->num_parameters())), LeaveCC, ne);
4283
4284 // Check if the calling frame is an arguments adaptor frame.
4285 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
4286 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
4287 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4288 __ b(ne, &exit);
4289 4289
4290 // Arguments adaptor case: Read the arguments length from the 4290 // Arguments adaptor case: Read the arguments length from the
4291 // adaptor frame. 4291 // adaptor frame.
4292 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 4292 __ ldr(tos,
4293 MemOperand(scratch0, ArgumentsAdaptorFrameConstants::kLengthOffset),
4294 eq);
4293 4295
4294 __ bind(&exit); 4296 frame_->EmitPush(tos);
4295 frame_->EmitPush(r0);
4296 } 4297 }
4297 4298
4298 4299
4299 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) { 4300 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
4300 VirtualFrame::SpilledScope spilled_scope(frame_); 4301 VirtualFrame::SpilledScope spilled_scope(frame_);
4301 ASSERT(args->length() == 1); 4302 ASSERT(args->length() == 1);
4302 4303
4303 // Satisfy contract with ArgumentsAccessStub: 4304 // Satisfy contract with ArgumentsAccessStub:
4304 // Load the key into r1 and the formal parameters count into r0. 4305 // Load the key into r1 and the formal parameters count into r0.
4305 LoadAndSpill(args->at(0)); 4306 LoadAndSpill(args->at(0));
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
4724 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { 4725 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
4725 ASSERT_EQ(args->length(), 1); 4726 ASSERT_EQ(args->length(), 1);
4726 // Load the argument on the stack and jump to the runtime. 4727 // Load the argument on the stack and jump to the runtime.
4727 Load(args->at(0)); 4728 Load(args->at(0));
4728 frame_->CallRuntime(Runtime::kMath_cos, 1); 4729 frame_->CallRuntime(Runtime::kMath_cos, 1);
4729 frame_->EmitPush(r0); 4730 frame_->EmitPush(r0);
4730 } 4731 }
4731 4732
4732 4733
4733 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { 4734 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
4734 VirtualFrame::SpilledScope spilled_scope(frame_);
4735 ASSERT(args->length() == 2); 4735 ASSERT(args->length() == 2);
4736 4736
4737 // Load the two objects into registers and perform the comparison. 4737 // Load the two objects into registers and perform the comparison.
4738 LoadAndSpill(args->at(0)); 4738 Load(args->at(0));
4739 LoadAndSpill(args->at(1)); 4739 Load(args->at(1));
4740 frame_->EmitPop(r0); 4740 Register lhs = frame_->PopToRegister();
4741 frame_->EmitPop(r1); 4741 Register rhs = frame_->PopToRegister(lhs);
4742 __ cmp(r0, r1); 4742 __ cmp(lhs, rhs);
4743 cc_reg_ = eq; 4743 cc_reg_ = eq;
4744 } 4744 }
4745 4745
4746 4746
4747 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { 4747 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
4748 #ifdef DEBUG 4748 #ifdef DEBUG
4749 int original_height = frame_->height(); 4749 int original_height = frame_->height();
4750 #endif 4750 #endif
4751 VirtualFrame::SpilledScope spilled_scope(frame_); 4751 VirtualFrame::SpilledScope spilled_scope(frame_);
4752 if (CheckForInlineRuntimeCall(node)) { 4752 if (CheckForInlineRuntimeCall(node)) {
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
5031 // operators must yield the result of one of the two expressions 5031 // operators must yield the result of one of the two expressions
5032 // before any ToBoolean() conversions. This means that the value 5032 // before any ToBoolean() conversions. This means that the value
5033 // produced by a && or || operator is not necessarily a boolean. 5033 // produced by a && or || operator is not necessarily a boolean.
5034 5034
5035 // NOTE: If the left hand side produces a materialized value (not in 5035 // NOTE: If the left hand side produces a materialized value (not in
5036 // the CC register), we force the right hand side to do the 5036 // the CC register), we force the right hand side to do the
5037 // same. This is necessary because we may have to branch to the exit 5037 // same. This is necessary because we may have to branch to the exit
5038 // after evaluating the left hand side (due to the shortcut 5038 // after evaluating the left hand side (due to the shortcut
5039 // semantics), but the compiler must (statically) know if the result 5039 // semantics), but the compiler must (statically) know if the result
5040 // of compiling the binary operation is materialized or not. 5040 // of compiling the binary operation is materialized or not.
5041 VirtualFrame::SpilledScope spilled_scope(frame_);
5041 if (node->op() == Token::AND) { 5042 if (node->op() == Token::AND) {
5042 JumpTarget is_true; 5043 JumpTarget is_true;
5043 LoadConditionAndSpill(node->left(), 5044 LoadConditionAndSpill(node->left(),
5044 &is_true, 5045 &is_true,
5045 false_target(), 5046 false_target(),
5046 false); 5047 false);
5047 if (has_valid_frame() && !has_cc()) { 5048 if (has_valid_frame() && !has_cc()) {
5048 // The left-hand side result is on top of the virtual frame. 5049 // The left-hand side result is on top of the virtual frame.
5049 JumpTarget pop_and_continue; 5050 JumpTarget pop_and_continue;
5050 JumpTarget exit; 5051 JumpTarget exit;
5051 5052
5052 __ ldr(r0, frame_->Top()); // Duplicate the stack top. 5053 frame_->Dup();
5053 frame_->EmitPush(r0);
5054 // Avoid popping the result if it converts to 'false' using the 5054 // Avoid popping the result if it converts to 'false' using the
5055 // standard ToBoolean() conversion as described in ECMA-262, 5055 // standard ToBoolean() conversion as described in ECMA-262,
5056 // section 9.2, page 30. 5056 // section 9.2, page 30.
5057 ToBoolean(&pop_and_continue, &exit); 5057 ToBoolean(&pop_and_continue, &exit);
5058 Branch(false, &exit); 5058 Branch(false, &exit);
5059 5059
5060 // Pop the result of evaluating the first part. 5060 // Pop the result of evaluating the first part.
5061 pop_and_continue.Bind(); 5061 pop_and_continue.Bind();
5062 frame_->EmitPop(r0); 5062 frame_->Pop();
5063 5063
5064 // Evaluate right side expression. 5064 // Evaluate right side expression.
5065 is_true.Bind(); 5065 is_true.Bind();
5066 LoadAndSpill(node->right()); 5066 LoadAndSpill(node->right());
5067 5067
5068 // Exit (always with a materialized value). 5068 // Exit (always with a materialized value).
5069 exit.Bind(); 5069 exit.Bind();
5070 } else if (has_cc() || is_true.is_linked()) { 5070 } else if (has_cc() || is_true.is_linked()) {
5071 // The left-hand side is either (a) partially compiled to 5071 // The left-hand side is either (a) partially compiled to
5072 // control flow with a final branch left to emit or (b) fully 5072 // control flow with a final branch left to emit or (b) fully
(...skipping 16 matching lines...) Expand all
5089 JumpTarget is_false; 5089 JumpTarget is_false;
5090 LoadConditionAndSpill(node->left(), 5090 LoadConditionAndSpill(node->left(),
5091 true_target(), 5091 true_target(),
5092 &is_false, 5092 &is_false,
5093 false); 5093 false);
5094 if (has_valid_frame() && !has_cc()) { 5094 if (has_valid_frame() && !has_cc()) {
5095 // The left-hand side result is on top of the virtual frame. 5095 // The left-hand side result is on top of the virtual frame.
5096 JumpTarget pop_and_continue; 5096 JumpTarget pop_and_continue;
5097 JumpTarget exit; 5097 JumpTarget exit;
5098 5098
5099 __ ldr(r0, frame_->Top()); 5099 frame_->Dup();
5100 frame_->EmitPush(r0);
5101 // Avoid popping the result if it converts to 'true' using the 5100 // Avoid popping the result if it converts to 'true' using the
5102 // standard ToBoolean() conversion as described in ECMA-262, 5101 // standard ToBoolean() conversion as described in ECMA-262,
5103 // section 9.2, page 30. 5102 // section 9.2, page 30.
5104 ToBoolean(&exit, &pop_and_continue); 5103 ToBoolean(&exit, &pop_and_continue);
5105 Branch(true, &exit); 5104 Branch(true, &exit);
5106 5105
5107 // Pop the result of evaluating the first part. 5106 // Pop the result of evaluating the first part.
5108 pop_and_continue.Bind(); 5107 pop_and_continue.Bind();
5109 frame_->EmitPop(r0); 5108 frame_->Pop();
5110 5109
5111 // Evaluate right side expression. 5110 // Evaluate right side expression.
5112 is_false.Bind(); 5111 is_false.Bind();
5113 LoadAndSpill(node->right()); 5112 LoadAndSpill(node->right());
5114 5113
5115 // Exit (always with a materialized value). 5114 // Exit (always with a materialized value).
5116 exit.Bind(); 5115 exit.Bind();
5117 } else if (has_cc() || is_false.is_linked()) { 5116 } else if (has_cc() || is_false.is_linked()) {
5118 // The left-hand side is either (a) partially compiled to 5117 // The left-hand side is either (a) partially compiled to
5119 // control flow with a final branch left to emit or (b) fully 5118 // control flow with a final branch left to emit or (b) fully
(...skipping 14 matching lines...) Expand all
5134 } 5133 }
5135 5134
5136 5135
5137 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { 5136 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
5138 #ifdef DEBUG 5137 #ifdef DEBUG
5139 int original_height = frame_->height(); 5138 int original_height = frame_->height();
5140 #endif 5139 #endif
5141 Comment cmnt(masm_, "[ BinaryOperation"); 5140 Comment cmnt(masm_, "[ BinaryOperation");
5142 5141
5143 if (node->op() == Token::AND || node->op() == Token::OR) { 5142 if (node->op() == Token::AND || node->op() == Token::OR) {
5144 VirtualFrame::SpilledScope spilled_scope(frame_);
5145 GenerateLogicalBooleanOperation(node); 5143 GenerateLogicalBooleanOperation(node);
5146 } else { 5144 } else {
5147 // Optimize for the case where (at least) one of the expressions 5145 // Optimize for the case where (at least) one of the expressions
5148 // is a literal small integer. 5146 // is a literal small integer.
5149 Literal* lliteral = node->left()->AsLiteral(); 5147 Literal* lliteral = node->left()->AsLiteral();
5150 Literal* rliteral = node->right()->AsLiteral(); 5148 Literal* rliteral = node->right()->AsLiteral();
5151 // NOTE: The code below assumes that the slow cases (calls to runtime) 5149 // NOTE: The code below assumes that the slow cases (calls to runtime)
5152 // never return a constant/immutable object. 5150 // never return a constant/immutable object.
5153 bool overwrite_left = 5151 bool overwrite_left =
5154 (node->left()->AsBinaryOperation() != NULL && 5152 (node->left()->AsBinaryOperation() != NULL &&
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5187 ASSERT(!has_valid_frame() || 5185 ASSERT(!has_valid_frame() ||
5188 (has_cc() && frame_->height() == original_height) || 5186 (has_cc() && frame_->height() == original_height) ||
5189 (!has_cc() && frame_->height() == original_height + 1)); 5187 (!has_cc() && frame_->height() == original_height + 1));
5190 } 5188 }
5191 5189
5192 5190
5193 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 5191 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
5194 #ifdef DEBUG 5192 #ifdef DEBUG
5195 int original_height = frame_->height(); 5193 int original_height = frame_->height();
5196 #endif 5194 #endif
5197 VirtualFrame::SpilledScope spilled_scope(frame_); 5195 frame_->EmitPush(MemOperand(frame_->Function()));
5198 __ ldr(r0, frame_->Function());
5199 frame_->EmitPush(r0);
5200 ASSERT_EQ(original_height + 1, frame_->height()); 5196 ASSERT_EQ(original_height + 1, frame_->height());
5201 } 5197 }
5202 5198
5203 5199
5204 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 5200 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
5205 #ifdef DEBUG 5201 #ifdef DEBUG
5206 int original_height = frame_->height(); 5202 int original_height = frame_->height();
5207 #endif 5203 #endif
5208 Comment cmnt(masm_, "[ CompareOperation"); 5204 Comment cmnt(masm_, "[ CompareOperation");
5209 5205
(...skipping 4825 matching lines...) Expand 10 before | Expand all | Expand 10 after
10035 __ bind(&string_add_runtime); 10031 __ bind(&string_add_runtime);
10036 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 10032 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
10037 } 10033 }
10038 10034
10039 10035
10040 #undef __ 10036 #undef __
10041 10037
10042 } } // namespace v8::internal 10038 } } // namespace v8::internal
10043 10039
10044 #endif // V8_TARGET_ARCH_ARM 10040 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698