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

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

Issue 594008: Initial implementation of fast path operation for bitwise OR. (Closed)
Patch Set: Fixed bug, added test. 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.cc ('k') | src/x64/fast-codegen-x64.cc » ('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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 44
45 45
46 void FastCodeGenerator::EmitLoadReceiver() { 46 void FastCodeGenerator::EmitLoadReceiver() {
47 // Offset 2 is due to return address and saved frame pointer. 47 // Offset 2 is due to return address and saved frame pointer.
48 int index = 2 + function()->scope()->num_parameters(); 48 int index = 2 + function()->scope()->num_parameters();
49 __ mov(receiver_reg(), Operand(ebp, index * kPointerSize)); 49 __ mov(receiver_reg(), Operand(ebp, index * kPointerSize));
50 } 50 }
51 51
52 52
53 void FastCodeGenerator::EmitGlobalVariableLoad(Handle<Object> cell) { 53 void FastCodeGenerator::EmitGlobalVariableLoad(Handle<Object> cell) {
54 ASSERT(!destination().is(no_reg));
54 ASSERT(cell->IsJSGlobalPropertyCell()); 55 ASSERT(cell->IsJSGlobalPropertyCell());
55 __ mov(accumulator0(), Immediate(cell)); 56
56 __ mov(accumulator0(), 57 __ mov(destination(), Immediate(cell));
57 FieldOperand(accumulator0(), JSGlobalPropertyCell::kValueOffset)); 58 __ mov(destination(),
59 FieldOperand(destination(), JSGlobalPropertyCell::kValueOffset));
58 if (FLAG_debug_code) { 60 if (FLAG_debug_code) {
59 __ cmp(accumulator0(), Factory::the_hole_value()); 61 __ cmp(destination(), Factory::the_hole_value());
60 __ Check(not_equal, "DontDelete cells can't contain the hole"); 62 __ Check(not_equal, "DontDelete cells can't contain the hole");
61 } 63 }
62 } 64 }
63 65
64 66
65 void FastCodeGenerator::EmitThisPropertyStore(Handle<String> name) { 67 void FastCodeGenerator::EmitThisPropertyStore(Handle<String> name) {
66 LookupResult lookup; 68 LookupResult lookup;
67 info()->receiver()->Lookup(*name, &lookup); 69 info()->receiver()->Lookup(*name, &lookup);
68 70
69 ASSERT(lookup.holder() == *info()->receiver()); 71 ASSERT(lookup.holder() == *info()->receiver());
70 ASSERT(lookup.type() == FIELD); 72 ASSERT(lookup.type() == FIELD);
71 Handle<Map> map(Handle<HeapObject>::cast(info()->receiver())->map()); 73 Handle<Map> map(Handle<HeapObject>::cast(info()->receiver())->map());
72 int index = lookup.GetFieldIndex() - map->inobject_properties(); 74 int index = lookup.GetFieldIndex() - map->inobject_properties();
73 int offset = index * kPointerSize; 75 int offset = index * kPointerSize;
74 76
75 // Negative offsets are inobject properties. 77 // Negative offsets are inobject properties.
76 if (offset < 0) { 78 if (offset < 0) {
77 offset += map->instance_size(); 79 offset += map->instance_size();
78 __ mov(scratch0(), receiver_reg()); // Copy receiver for write barrier. 80 __ mov(scratch0(), receiver_reg()); // Copy receiver for write barrier.
79 } else { 81 } else {
80 offset += FixedArray::kHeaderSize; 82 offset += FixedArray::kHeaderSize;
81 __ mov(scratch0(), 83 __ mov(scratch0(),
82 FieldOperand(receiver_reg(), JSObject::kPropertiesOffset)); 84 FieldOperand(receiver_reg(), JSObject::kPropertiesOffset));
83 } 85 }
84 // Perform the store. 86 // Perform the store.
85 __ mov(FieldOperand(scratch0(), offset), accumulator0()); 87 __ mov(FieldOperand(scratch0(), offset), accumulator0());
86 // Preserve value from write barrier in case it's needed. 88 if (destination().is(no_reg)) {
87 __ mov(accumulator1(), accumulator0()); 89 __ RecordWrite(scratch0(), offset, accumulator0(), scratch1());
88 // The other accumulator register is available as a scratch register 90 } else {
89 // because this is not an AST leaf node. 91 // Copy the value to the other accumulator to preserve a copy from the
90 __ RecordWrite(scratch0(), offset, accumulator1(), scratch1()); 92 // write barrier. One of the accumulators is available as a scratch
93 // register.
94 __ mov(accumulator1(), accumulator0());
95 Register value_scratch = other_accumulator(destination());
96 __ RecordWrite(scratch0(), offset, value_scratch, scratch1());
97 }
91 } 98 }
92 99
93 100
101 void FastCodeGenerator::EmitThisPropertyLoad(Handle<String> name) {
102 ASSERT(!destination().is(no_reg));
103 LookupResult lookup;
104 info()->receiver()->Lookup(*name, &lookup);
105
106 ASSERT(lookup.holder() == *info()->receiver());
107 ASSERT(lookup.type() == FIELD);
108 Handle<Map> map(Handle<HeapObject>::cast(info()->receiver())->map());
109 int index = lookup.GetFieldIndex() - map->inobject_properties();
110 int offset = index * kPointerSize;
111
112 // Perform the load. Negative offsets are inobject properties.
113 if (offset < 0) {
114 offset += map->instance_size();
115 __ mov(destination(), FieldOperand(receiver_reg(), offset));
116 } else {
117 offset += FixedArray::kHeaderSize;
118 __ mov(scratch0(),
119 FieldOperand(receiver_reg(), JSObject::kPropertiesOffset));
120 __ mov(destination(), FieldOperand(scratch0(), offset));
121 }
122 }
123
124
125 void FastCodeGenerator::EmitBitOr() {
126 Register copied; // One operand is copied to a scratch register.
127 Register other; // The other is not modified by the operation.
128 Register check; // A register is used for the smi check/operation.
129 if (destination().is(no_reg)) {
130 copied = accumulator1(); // Arbitrary choice of operand to copy.
131 other = accumulator0();
132 check = scratch0(); // Do not clobber either operand register.
133 } else {
134 copied = destination();
135 other = other_accumulator(destination());
136 check = destination();
137 }
138 __ mov(scratch0(), copied);
139 __ or_(check, Operand(other));
140 __ test(check, Immediate(kSmiTagMask));
141
142 // Restore the clobbered operand if necessary.
143 if (destination().is(no_reg)) {
144 __ j(not_zero, bailout(), not_taken);
145 } else {
146 Label done;
147 __ j(zero, &done, taken);
148 __ mov(copied, scratch0());
149 __ jmp(bailout());
150 __ bind(&done);
151 }
152 }
153
154
94 void FastCodeGenerator::Generate(CompilationInfo* compilation_info) { 155 void FastCodeGenerator::Generate(CompilationInfo* compilation_info) {
95 ASSERT(info_ == NULL); 156 ASSERT(info_ == NULL);
96 info_ = compilation_info; 157 info_ = compilation_info;
97 158
98 // Save the caller's frame pointer and set up our own. 159 // Save the caller's frame pointer and set up our own.
99 Comment prologue_cmnt(masm(), ";; Prologue"); 160 Comment prologue_cmnt(masm(), ";; Prologue");
100 __ push(ebp); 161 __ push(ebp);
101 __ mov(ebp, esp); 162 __ mov(ebp, esp);
102 __ push(esi); // Context. 163 __ push(esi); // Context.
103 __ push(edi); // Closure. 164 __ push(edi); // Closure.
104 // Note that we keep a live register reference to esi (context) at this 165 // Note that we keep a live register reference to esi (context) at this
105 // point. 166 // point.
106 167
107 // Receiver (this) is allocated to a fixed register. 168 // Receiver (this) is allocated to a fixed register.
108 if (info()->has_this_properties()) { 169 if (info()->has_this_properties()) {
109 Comment cmnt(masm(), ";; MapCheck(this)"); 170 Comment cmnt(masm(), ";; MapCheck(this)");
110 if (FLAG_print_ir) { 171 if (FLAG_print_ir) {
111 PrintF("MapCheck(this)\n"); 172 PrintF("#: MapCheck(this)\n");
112 } 173 }
113 ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject()); 174 ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject());
114 Handle<HeapObject> object = Handle<HeapObject>::cast(info()->receiver()); 175 Handle<HeapObject> object = Handle<HeapObject>::cast(info()->receiver());
115 Handle<Map> map(object->map()); 176 Handle<Map> map(object->map());
116 EmitLoadReceiver(); 177 EmitLoadReceiver();
117 __ CheckMap(receiver_reg(), map, bailout(), false); 178 __ CheckMap(receiver_reg(), map, bailout(), false);
118 } 179 }
119 180
120 // If there is a global variable access check if the global object is the 181 // If there is a global variable access check if the global object is the
121 // same as at lazy-compilation time. 182 // same as at lazy-compilation time.
122 if (info()->has_globals()) { 183 if (info()->has_globals()) {
123 Comment cmnt(masm(), ";; MapCheck(GLOBAL)"); 184 Comment cmnt(masm(), ";; MapCheck(GLOBAL)");
124 if (FLAG_print_ir) { 185 if (FLAG_print_ir) {
125 PrintF("MapCheck(GLOBAL)\n"); 186 PrintF("#: MapCheck(GLOBAL)\n");
126 } 187 }
127 ASSERT(info()->has_global_object()); 188 ASSERT(info()->has_global_object());
128 Handle<Map> map(info()->global_object()->map()); 189 Handle<Map> map(info()->global_object()->map());
129 __ mov(scratch0(), CodeGenerator::GlobalObject()); 190 __ mov(scratch0(), CodeGenerator::GlobalObject());
130 __ CheckMap(scratch0(), map, bailout(), true); 191 __ CheckMap(scratch0(), map, bailout(), true);
131 } 192 }
132 193
133 VisitStatements(function()->body()); 194 VisitStatements(function()->body());
134 195
135 Comment return_cmnt(masm(), ";; Return(<undefined>)"); 196 Comment return_cmnt(masm(), ";; Return(<undefined>)");
136 if (FLAG_print_ir) { 197 if (FLAG_print_ir) {
137 PrintF("Return(<undefined>)\n"); 198 PrintF("#: Return(<undefined>)\n");
138 } 199 }
139 __ mov(eax, Factory::undefined_value()); 200 __ mov(eax, Factory::undefined_value());
140 __ mov(esp, ebp); 201 __ mov(esp, ebp);
141 __ pop(ebp); 202 __ pop(ebp);
142 __ ret((scope()->num_parameters() + 1) * kPointerSize); 203 __ ret((scope()->num_parameters() + 1) * kPointerSize);
143 204
144 __ bind(&bailout_); 205 __ bind(&bailout_);
145 } 206 }
146 207
147 208
148 #undef __ 209 #undef __
149 210
150 211
151 } } // namespace v8::internal 212 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.cc ('k') | src/x64/fast-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698