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

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

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 3 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/arm/frames-arm.h ('k') | src/arm/lithium-arm.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 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 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 kDontSaveFPRegs, 745 kDontSaveFPRegs,
746 EMIT_REMEMBERED_SET, 746 EMIT_REMEMBERED_SET,
747 OMIT_SMI_CHECK); 747 OMIT_SMI_CHECK);
748 } 748 }
749 break; 749 break;
750 750
751 case Slot::LOOKUP: { 751 case Slot::LOOKUP: {
752 __ mov(r2, Operand(variable->name())); 752 __ mov(r2, Operand(variable->name()));
753 // Declaration nodes are always introduced in one of two modes. 753 // Declaration nodes are always introduced in one of two modes.
754 ASSERT(mode == Variable::VAR || 754 ASSERT(mode == Variable::VAR ||
755 mode == Variable::CONST); 755 mode == Variable::CONST ||
756 PropertyAttributes attr = 756 mode == Variable::LET);
757 (mode == Variable::VAR) ? NONE : READ_ONLY; 757 PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE;
758 __ mov(r1, Operand(Smi::FromInt(attr))); 758 __ mov(r1, Operand(Smi::FromInt(attr)));
759 // Push initial value, if any. 759 // Push initial value, if any.
760 // Note: For variables we must not push an initial value (such as 760 // Note: For variables we must not push an initial value (such as
761 // 'undefined') because we may have a (legal) redeclaration and we 761 // 'undefined') because we may have a (legal) redeclaration and we
762 // must not destroy the current value. 762 // must not destroy the current value.
763 if (mode == Variable::CONST) { 763 if (mode == Variable::CONST) {
764 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 764 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
765 __ Push(cp, r2, r1, r0); 765 __ Push(cp, r2, r1, r0);
766 } else if (function != NULL) { 766 } else if (function != NULL) {
767 __ Push(cp, r2, r1); 767 __ Push(cp, r2, r1);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 __ b(ne, &next_test); 881 __ b(ne, &next_test);
882 __ Drop(1); // Switch value is no longer needed. 882 __ Drop(1); // Switch value is no longer needed.
883 __ b(clause->body_target()); 883 __ b(clause->body_target());
884 } 884 }
885 885
886 // Discard the test value and jump to the default if present, otherwise to 886 // Discard the test value and jump to the default if present, otherwise to
887 // the end of the statement. 887 // the end of the statement.
888 __ bind(&next_test); 888 __ bind(&next_test);
889 __ Drop(1); // Switch value is no longer needed. 889 __ Drop(1); // Switch value is no longer needed.
890 if (default_clause == NULL) { 890 if (default_clause == NULL) {
891 __ b(nested_statement.break_target()); 891 __ b(nested_statement.break_label());
892 } else { 892 } else {
893 __ b(default_clause->body_target()); 893 __ b(default_clause->body_target());
894 } 894 }
895 895
896 // Compile all the case bodies. 896 // Compile all the case bodies.
897 for (int i = 0; i < clauses->length(); i++) { 897 for (int i = 0; i < clauses->length(); i++) {
898 Comment cmnt(masm_, "[ Case body"); 898 Comment cmnt(masm_, "[ Case body");
899 CaseClause* clause = clauses->at(i); 899 CaseClause* clause = clauses->at(i);
900 __ bind(clause->body_target()); 900 __ bind(clause->body_target());
901 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 901 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
902 VisitStatements(clause->statements()); 902 VisitStatements(clause->statements());
903 } 903 }
904 904
905 __ bind(nested_statement.break_target()); 905 __ bind(nested_statement.break_label());
906 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 906 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
907 } 907 }
908 908
909 909
910 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 910 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
911 Comment cmnt(masm_, "[ ForInStatement"); 911 Comment cmnt(masm_, "[ ForInStatement");
912 SetStatementPosition(stmt); 912 SetStatementPosition(stmt);
913 913
914 Label loop, exit; 914 Label loop, exit;
915 ForIn loop_statement(this, stmt); 915 ForIn loop_statement(this, stmt);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 __ Push(r1, r0); 1026 __ Push(r1, r0);
1027 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset)); 1027 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset));
1028 __ mov(r0, Operand(Smi::FromInt(0))); 1028 __ mov(r0, Operand(Smi::FromInt(0)));
1029 __ Push(r1, r0); // Fixed array length (as smi) and initial index. 1029 __ Push(r1, r0); // Fixed array length (as smi) and initial index.
1030 1030
1031 // Generate code for doing the condition check. 1031 // Generate code for doing the condition check.
1032 __ bind(&loop); 1032 __ bind(&loop);
1033 // Load the current count to r0, load the length to r1. 1033 // Load the current count to r0, load the length to r1.
1034 __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize)); 1034 __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
1035 __ cmp(r0, r1); // Compare to the array length. 1035 __ cmp(r0, r1); // Compare to the array length.
1036 __ b(hs, loop_statement.break_target()); 1036 __ b(hs, loop_statement.break_label());
1037 1037
1038 // Get the current entry of the array into register r3. 1038 // Get the current entry of the array into register r3.
1039 __ ldr(r2, MemOperand(sp, 2 * kPointerSize)); 1039 __ ldr(r2, MemOperand(sp, 2 * kPointerSize));
1040 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 1040 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1041 __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize)); 1041 __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize));
1042 1042
1043 // Get the expected map from the stack or a zero map in the 1043 // Get the expected map from the stack or a zero map in the
1044 // permanent slow case into register r2. 1044 // permanent slow case into register r2.
1045 __ ldr(r2, MemOperand(sp, 3 * kPointerSize)); 1045 __ ldr(r2, MemOperand(sp, 3 * kPointerSize));
1046 1046
1047 // Check if the expected map still matches that of the enumerable. 1047 // Check if the expected map still matches that of the enumerable.
1048 // If not, we have to filter the key. 1048 // If not, we have to filter the key.
1049 Label update_each; 1049 Label update_each;
1050 __ ldr(r1, MemOperand(sp, 4 * kPointerSize)); 1050 __ ldr(r1, MemOperand(sp, 4 * kPointerSize));
1051 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); 1051 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
1052 __ cmp(r4, Operand(r2)); 1052 __ cmp(r4, Operand(r2));
1053 __ b(eq, &update_each); 1053 __ b(eq, &update_each);
1054 1054
1055 // Convert the entry to a string or (smi) 0 if it isn't a property 1055 // Convert the entry to a string or (smi) 0 if it isn't a property
1056 // any more. If the property has been removed while iterating, we 1056 // any more. If the property has been removed while iterating, we
1057 // just skip it. 1057 // just skip it.
1058 __ push(r1); // Enumerable. 1058 __ push(r1); // Enumerable.
1059 __ push(r3); // Current entry. 1059 __ push(r3); // Current entry.
1060 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); 1060 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION);
1061 __ mov(r3, Operand(r0), SetCC); 1061 __ mov(r3, Operand(r0), SetCC);
1062 __ b(eq, loop_statement.continue_target()); 1062 __ b(eq, loop_statement.continue_label());
1063 1063
1064 // Update the 'each' property or variable from the possibly filtered 1064 // Update the 'each' property or variable from the possibly filtered
1065 // entry in register r3. 1065 // entry in register r3.
1066 __ bind(&update_each); 1066 __ bind(&update_each);
1067 __ mov(result_register(), r3); 1067 __ mov(result_register(), r3);
1068 // Perform the assignment as if via '='. 1068 // Perform the assignment as if via '='.
1069 { EffectContext context(this); 1069 { EffectContext context(this);
1070 EmitAssignment(stmt->each(), stmt->AssignmentId()); 1070 EmitAssignment(stmt->each(), stmt->AssignmentId());
1071 } 1071 }
1072 1072
1073 // Generate code for the body of the loop. 1073 // Generate code for the body of the loop.
1074 Visit(stmt->body()); 1074 Visit(stmt->body());
1075 1075
1076 // Generate code for the going to the next element by incrementing 1076 // Generate code for the going to the next element by incrementing
1077 // the index (smi) stored on top of the stack. 1077 // the index (smi) stored on top of the stack.
1078 __ bind(loop_statement.continue_target()); 1078 __ bind(loop_statement.continue_label());
1079 __ pop(r0); 1079 __ pop(r0);
1080 __ add(r0, r0, Operand(Smi::FromInt(1))); 1080 __ add(r0, r0, Operand(Smi::FromInt(1)));
1081 __ push(r0); 1081 __ push(r0);
1082 1082
1083 EmitStackCheck(stmt); 1083 EmitStackCheck(stmt);
1084 __ b(&loop); 1084 __ b(&loop);
1085 1085
1086 // Remove the pointers stored on the stack. 1086 // Remove the pointers stored on the stack.
1087 __ bind(loop_statement.break_target()); 1087 __ bind(loop_statement.break_label());
1088 __ Drop(5); 1088 __ Drop(5);
1089 1089
1090 // Exit and decrement the loop depth. 1090 // Exit and decrement the loop depth.
1091 __ bind(&exit); 1091 __ bind(&exit);
1092 decrement_loop_depth(); 1092 decrement_loop_depth();
1093 } 1093 }
1094 1094
1095 1095
1096 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1096 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1097 bool pretenure) { 1097 bool pretenure) {
(...skipping 2949 matching lines...) Expand 10 before | Expand all | Expand 10 after
4047 __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE); 4047 __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE);
4048 __ b(ge, if_false); 4048 __ b(ge, if_false);
4049 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); 4049 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
4050 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 4050 __ tst(r1, Operand(1 << Map::kIsUndetectable));
4051 Split(eq, if_true, if_false, fall_through); 4051 Split(eq, if_true, if_false, fall_through);
4052 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { 4052 } else if (check->Equals(isolate()->heap()->boolean_symbol())) {
4053 __ CompareRoot(r0, Heap::kTrueValueRootIndex); 4053 __ CompareRoot(r0, Heap::kTrueValueRootIndex);
4054 __ b(eq, if_true); 4054 __ b(eq, if_true);
4055 __ CompareRoot(r0, Heap::kFalseValueRootIndex); 4055 __ CompareRoot(r0, Heap::kFalseValueRootIndex);
4056 Split(eq, if_true, if_false, fall_through); 4056 Split(eq, if_true, if_false, fall_through);
4057 } else if (FLAG_harmony_typeof &&
4058 check->Equals(isolate()->heap()->null_symbol())) {
4059 __ CompareRoot(r0, Heap::kNullValueRootIndex);
4060 Split(eq, if_true, if_false, fall_through);
4057 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { 4061 } else if (check->Equals(isolate()->heap()->undefined_symbol())) {
4058 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); 4062 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
4059 __ b(eq, if_true); 4063 __ b(eq, if_true);
4060 __ JumpIfSmi(r0, if_false); 4064 __ JumpIfSmi(r0, if_false);
4061 // Check for undetectable objects => true. 4065 // Check for undetectable objects => true.
4062 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); 4066 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
4063 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); 4067 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
4064 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 4068 __ tst(r1, Operand(1 << Map::kIsUndetectable));
4065 Split(ne, if_true, if_false, fall_through); 4069 Split(ne, if_true, if_false, fall_through);
4066 4070
4067 } else if (check->Equals(isolate()->heap()->function_symbol())) { 4071 } else if (check->Equals(isolate()->heap()->function_symbol())) {
4068 __ JumpIfSmi(r0, if_false); 4072 __ JumpIfSmi(r0, if_false);
4069 __ CompareObjectType(r0, r1, r0, FIRST_CALLABLE_SPEC_OBJECT_TYPE); 4073 __ CompareObjectType(r0, r1, r0, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
4070 Split(ge, if_true, if_false, fall_through); 4074 Split(ge, if_true, if_false, fall_through);
4071 4075
4072 } else if (check->Equals(isolate()->heap()->object_symbol())) { 4076 } else if (check->Equals(isolate()->heap()->object_symbol())) {
4073 __ JumpIfSmi(r0, if_false); 4077 __ JumpIfSmi(r0, if_false);
4074 __ CompareRoot(r0, Heap::kNullValueRootIndex); 4078 if (!FLAG_harmony_typeof) {
4075 __ b(eq, if_true); 4079 __ CompareRoot(r0, Heap::kNullValueRootIndex);
4080 __ b(eq, if_true);
4081 }
4076 // Check for JS objects => true. 4082 // Check for JS objects => true.
4077 __ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 4083 __ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
4078 __ b(lt, if_false); 4084 __ b(lt, if_false);
4079 __ CompareInstanceType(r0, r1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4085 __ CompareInstanceType(r0, r1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
4080 __ b(gt, if_false); 4086 __ b(gt, if_false);
4081 // Check for undetectable objects => false. 4087 // Check for undetectable objects => false.
4082 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); 4088 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
4083 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 4089 __ tst(r1, Operand(1 << Map::kIsUndetectable));
4084 Split(eq, if_true, if_false, fall_through); 4090 Split(eq, if_true, if_false, fall_through);
4085 } else { 4091 } else {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4140 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4146 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4141 // The stub returns 0 for true. 4147 // The stub returns 0 for true.
4142 __ tst(r0, r0); 4148 __ tst(r0, r0);
4143 Split(eq, if_true, if_false, fall_through); 4149 Split(eq, if_true, if_false, fall_through);
4144 break; 4150 break;
4145 } 4151 }
4146 4152
4147 default: { 4153 default: {
4148 VisitForAccumulatorValue(expr->right()); 4154 VisitForAccumulatorValue(expr->right());
4149 Condition cond = eq; 4155 Condition cond = eq;
4150 bool strict = false;
4151 switch (op) { 4156 switch (op) {
4152 case Token::EQ_STRICT: 4157 case Token::EQ_STRICT:
4153 strict = true;
4154 // Fall through
4155 case Token::EQ: 4158 case Token::EQ:
4156 cond = eq; 4159 cond = eq;
4157 __ pop(r1); 4160 __ pop(r1);
4158 break; 4161 break;
4159 case Token::LT: 4162 case Token::LT:
4160 cond = lt; 4163 cond = lt;
4161 __ pop(r1); 4164 __ pop(r1);
4162 break; 4165 break;
4163 case Token::GT: 4166 case Token::GT:
4164 // Reverse left and right sides to obtain ECMA-262 conversion order. 4167 // Reverse left and right sides to obtain ECMA-262 conversion order.
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
4316 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4319 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4317 __ add(pc, r1, Operand(masm_->CodeObject())); 4320 __ add(pc, r1, Operand(masm_->CodeObject()));
4318 } 4321 }
4319 4322
4320 4323
4321 #undef __ 4324 #undef __
4322 4325
4323 } } // namespace v8::internal 4326 } } // namespace v8::internal
4324 4327
4325 #endif // V8_TARGET_ARCH_ARM 4328 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/frames-arm.h ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698