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

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

Issue 9320: Semi-weekly merge from bleeding_edge to the toiger branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years, 1 month 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/codegen-arm.cc ('k') | src/compiler.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 1571 matching lines...) Expand 10 before | Expand all | Expand 10 after
1582 Vector<JumpTarget*> case_targets, 1582 Vector<JumpTarget*> case_targets,
1583 Vector<JumpTarget> case_labels) { 1583 Vector<JumpTarget> case_labels) {
1584 // Notice: Internal references, used by both the jmp instruction and 1584 // Notice: Internal references, used by both the jmp instruction and
1585 // the table entries, need to be relocated if the buffer grows. This 1585 // the table entries, need to be relocated if the buffer grows. This
1586 // prevents the forward use of Labels, since a displacement cannot 1586 // prevents the forward use of Labels, since a displacement cannot
1587 // survive relocation, and it also cannot safely be distinguished 1587 // survive relocation, and it also cannot safely be distinguished
1588 // from a real address. Instead we put in zero-values as 1588 // from a real address. Instead we put in zero-values as
1589 // placeholders, and fill in the addresses after the labels have been 1589 // placeholders, and fill in the addresses after the labels have been
1590 // bound. 1590 // bound.
1591 1591
1592 frame_->Pop(eax); // supposed smi 1592 frame_->Pop(eax); // supposed Smi
1593 // check range of value, if outside [0..length-1] jump to default/end label. 1593 // check range of value, if outside [0..length-1] jump to default/end label.
1594 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 1594 ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
1595
1596 // Test whether input is a HeapNumber that is really a Smi
1597 JumpTarget is_smi(this);
1598 __ test(eax, Immediate(kSmiTagMask));
1599 is_smi.Branch(equal);
1600 // It's a heap object, not a Smi or a Failure
1601 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
1602 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
1603 __ cmp(ebx, HEAP_NUMBER_TYPE);
1604 fail_label->Branch(not_equal);
1605 // eax points to a heap number.
1606 __ push(eax);
1607 __ CallRuntime(Runtime::kNumberToSmi, 1);
1608 is_smi.Bind();
1609
1595 if (min_index != 0) { 1610 if (min_index != 0) {
1596 __ sub(Operand(eax), Immediate(min_index << kSmiTagSize)); 1611 __ sub(Operand(eax), Immediate(min_index << kSmiTagSize));
1597 } 1612 }
1598 __ test(eax, Immediate(0x80000000 | kSmiTagMask)); // negative or not Smi 1613 __ test(eax, Immediate(0x80000000 | kSmiTagMask)); // negative or not Smi
1599 fail_label->Branch(not_equal, not_taken); 1614 fail_label->Branch(not_equal, not_taken);
1600 __ cmp(eax, range << kSmiTagSize); 1615 __ cmp(eax, range << kSmiTagSize);
1601 fail_label->Branch(greater_equal, not_taken); 1616 fail_label->Branch(greater_equal, not_taken);
1602 1617
1603 // 0 is placeholder. 1618 // 0 is placeholder.
1604 __ jmp(Operand(eax, times_2, 0x0, RelocInfo::INTERNAL_REFERENCE)); 1619 __ jmp(Operand(eax, times_2, 0x0, RelocInfo::INTERNAL_REFERENCE));
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
2112 exit.Jump(); 2127 exit.Jump();
2113 } 2128 }
2114 2129
2115 2130
2116 // --- Try block --- 2131 // --- Try block ---
2117 try_block.Bind(); 2132 try_block.Bind();
2118 2133
2119 frame_->PushTryHandler(TRY_CATCH_HANDLER); 2134 frame_->PushTryHandler(TRY_CATCH_HANDLER);
2120 int handler_height = frame_->height(); 2135 int handler_height = frame_->height();
2121 2136
2122 // Shadow the labels for all escapes from the try block, including 2137 // Shadow the jump targets for all escapes from the try block, including
2123 // returns. During shadowing, the original label is hidden as the 2138 // returns. During shadowing, the original target is hidden as the
2124 // LabelShadow and operations on the original actually affect the 2139 // ShadowTarget and operations on the original actually affect the
2125 // shadowing label. 2140 // shadowing target.
2126 // 2141 //
2127 // We should probably try to unify the escaping labels and the return 2142 // We should probably try to unify the escaping targets and the return
2128 // label. 2143 // target.
2129 int nof_escapes = node->escaping_targets()->length(); 2144 int nof_escapes = node->escaping_targets()->length();
2130 List<ShadowTarget*> shadows(1 + nof_escapes); 2145 List<ShadowTarget*> shadows(1 + nof_escapes);
2131 shadows.Add(new ShadowTarget(&function_return_)); 2146 shadows.Add(new ShadowTarget(&function_return_));
2132 for (int i = 0; i < nof_escapes; i++) { 2147 for (int i = 0; i < nof_escapes; i++) {
2133 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); 2148 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
2134 } 2149 }
2135 bool function_return_was_shadowed = function_return_is_shadowed_; 2150 bool function_return_was_shadowed = function_return_is_shadowed_;
2136 function_return_is_shadowed_ = true; 2151 function_return_is_shadowed_ = true;
2137 2152
2138 // Generate code for the statements in the try block. 2153 // Generate code for the statements in the try block.
2139 bool was_inside_try = is_inside_try_; 2154 bool was_inside_try = is_inside_try_;
2140 is_inside_try_ = true; 2155 is_inside_try_ = true;
2141 VisitStatements(node->try_block()->statements()); 2156 VisitStatements(node->try_block()->statements());
2142 is_inside_try_ = was_inside_try; 2157 is_inside_try_ = was_inside_try;
2143 2158
2144 // Stop the introduced shadowing and count the number of required unlinks. 2159 // Stop the introduced shadowing and count the number of required unlinks.
2145 // After shadowing stops, the original labels are unshadowed and the 2160 // After shadowing stops, the original targets are unshadowed and the
2146 // LabelShadows represent the formerly shadowing labels. 2161 // ShadowTargets represent the formerly shadowing targets.
2147 int nof_unlinks = 0; 2162 int nof_unlinks = 0;
2148 for (int i = 0; i <= nof_escapes; i++) { 2163 for (int i = 0; i <= nof_escapes; i++) {
2149 shadows[i]->StopShadowing(); 2164 shadows[i]->StopShadowing();
2150 if (shadows[i]->is_linked()) nof_unlinks++; 2165 if (shadows[i]->is_linked()) nof_unlinks++;
2151 } 2166 }
2152 function_return_is_shadowed_ = function_return_was_shadowed; 2167 function_return_is_shadowed_ = function_return_was_shadowed;
2153 2168
2154 // Get an external reference to the handler address. 2169 // Get an external reference to the handler address.
2155 ExternalReference handler_address(Top::k_handler_address); 2170 ExternalReference handler_address(Top::k_handler_address);
2156 2171
(...skipping 10 matching lines...) Expand all
2167 if (frame_ != NULL) { 2182 if (frame_ != NULL) {
2168 frame_->Pop(eax); 2183 frame_->Pop(eax);
2169 __ mov(Operand::StaticVariable(handler_address), eax); // TOS == next_sp 2184 __ mov(Operand::StaticVariable(handler_address), eax); // TOS == next_sp
2170 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 2185 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2171 // next_sp popped. 2186 // next_sp popped.
2172 if (nof_unlinks > 0) { 2187 if (nof_unlinks > 0) {
2173 exit.Jump(); 2188 exit.Jump();
2174 } 2189 }
2175 } 2190 }
2176 2191
2177 // Generate unlink code for the (formerly) shadowing labels that have been 2192 // Generate unlink code for the (formerly) shadowing targets that have been
2178 // jumped to. 2193 // jumped to.
2179 for (int i = 0; i <= nof_escapes; i++) { 2194 for (int i = 0; i <= nof_escapes; i++) {
2180 if (shadows[i]->is_linked()) { 2195 if (shadows[i]->is_linked()) {
2181 // Unlink from try chain; be careful not to destroy the TOS. 2196 // Unlink from try chain; be careful not to destroy the TOS.
2182 shadows[i]->Bind(); 2197 shadows[i]->Bind();
2183 2198
2184 // Reload sp from the top handler, because some statements that we 2199 // Reload sp from the top handler, because some statements that we
2185 // break from (eg, for...in) may have left stuff on the stack. 2200 // break from (eg, for...in) may have left stuff on the stack.
2186 __ mov(edx, Operand::StaticVariable(handler_address)); 2201 __ mov(edx, Operand::StaticVariable(handler_address));
2187 const int kNextOffset = StackHandlerConstants::kNextOffset + 2202 const int kNextOffset = StackHandlerConstants::kNextOffset +
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2221 __ Set(ecx, Immediate(Smi::FromInt(THROWING))); 2236 __ Set(ecx, Immediate(Smi::FromInt(THROWING)));
2222 finally_block.Jump(); 2237 finally_block.Jump();
2223 2238
2224 2239
2225 // --- Try block --- 2240 // --- Try block ---
2226 try_block.Bind(); 2241 try_block.Bind();
2227 2242
2228 frame_->PushTryHandler(TRY_FINALLY_HANDLER); 2243 frame_->PushTryHandler(TRY_FINALLY_HANDLER);
2229 int handler_height = frame_->height(); 2244 int handler_height = frame_->height();
2230 2245
2231 // Shadow the labels for all escapes from the try block, including 2246 // Shadow the jump targets for all escapes from the try block, including
2232 // returns. During shadowing, the original label is hidden as the 2247 // returns. During shadowing, the original target is hidden as the
2233 // LabelShadow and operations on the original actually affect the 2248 // ShadowTarget and operations on the original actually affect the
2234 // shadowing label. 2249 // shadowing target.
2235 // 2250 //
2236 // We should probably try to unify the escaping labels and the return 2251 // We should probably try to unify the escaping targets and the return
2237 // label. 2252 // target.
2238 int nof_escapes = node->escaping_targets()->length(); 2253 int nof_escapes = node->escaping_targets()->length();
2239 List<ShadowTarget*> shadows(1 + nof_escapes); 2254 List<ShadowTarget*> shadows(1 + nof_escapes);
2240 shadows.Add(new ShadowTarget(&function_return_)); 2255 shadows.Add(new ShadowTarget(&function_return_));
2241 for (int i = 0; i < nof_escapes; i++) { 2256 for (int i = 0; i < nof_escapes; i++) {
2242 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); 2257 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
2243 } 2258 }
2244 bool function_return_was_shadowed = function_return_is_shadowed_; 2259 bool function_return_was_shadowed = function_return_is_shadowed_;
2245 function_return_is_shadowed_ = true; 2260 function_return_is_shadowed_ = true;
2246 2261
2247 // Generate code for the statements in the try block. 2262 // Generate code for the statements in the try block.
2248 bool was_inside_try = is_inside_try_; 2263 bool was_inside_try = is_inside_try_;
2249 is_inside_try_ = true; 2264 is_inside_try_ = true;
2250 VisitStatements(node->try_block()->statements()); 2265 VisitStatements(node->try_block()->statements());
2251 is_inside_try_ = was_inside_try; 2266 is_inside_try_ = was_inside_try;
2252 2267
2253 // Stop the introduced shadowing and count the number of required unlinks. 2268 // Stop the introduced shadowing and count the number of required unlinks.
2254 // After shadowing stops, the original labels are unshadowed and the 2269 // After shadowing stops, the original targets are unshadowed and the
2255 // LabelShadows represent the formerly shadowing labels. 2270 // ShadowTargets represent the formerly shadowing targets.
2256 int nof_unlinks = 0; 2271 int nof_unlinks = 0;
2257 for (int i = 0; i <= nof_escapes; i++) { 2272 for (int i = 0; i <= nof_escapes; i++) {
2258 shadows[i]->StopShadowing(); 2273 shadows[i]->StopShadowing();
2259 if (shadows[i]->is_linked()) nof_unlinks++; 2274 if (shadows[i]->is_linked()) nof_unlinks++;
2260 } 2275 }
2261 function_return_is_shadowed_ = function_return_was_shadowed; 2276 function_return_is_shadowed_ = function_return_was_shadowed;
2262 2277
2263 // If we can fall off the end of the try block, set the state on the stack 2278 // If we can fall off the end of the try block, set the state on the stack
2264 // to FALLING. 2279 // to FALLING.
2265 if (frame_ != NULL) { 2280 if (frame_ != NULL) {
2266 frame_->Push(Immediate(Factory::undefined_value())); // fake TOS 2281 frame_->Push(Immediate(Factory::undefined_value())); // fake TOS
2267 __ Set(ecx, Immediate(Smi::FromInt(FALLING))); 2282 __ Set(ecx, Immediate(Smi::FromInt(FALLING)));
2268 if (nof_unlinks > 0) { 2283 if (nof_unlinks > 0) {
2269 unlink.Jump(); 2284 unlink.Jump();
2270 } 2285 }
2271 } 2286 }
2272 2287
2273 // Generate code to set the state for the (formerly) shadowing labels that 2288 // Generate code to set the state for the (formerly) shadowing targets that
2274 // have been jumped to. 2289 // have been jumped to.
2275 for (int i = 0; i <= nof_escapes; i++) { 2290 for (int i = 0; i <= nof_escapes; i++) {
2276 if (shadows[i]->is_linked()) { 2291 if (shadows[i]->is_linked()) {
2277 shadows[i]->Bind(); 2292 shadows[i]->Bind();
2278 if (shadows[i]->original_target() == &function_return_) { 2293 if (shadows[i]->original_target() == &function_return_) {
2279 // If this label shadowed the function return, materialize the 2294 // If this target shadowed the function return, materialize the
2280 // return value on the stack. 2295 // return value on the stack.
2281 frame_->Push(eax); 2296 frame_->Push(eax);
2282 } else { 2297 } else {
2283 // Fake TOS for labels that shadowed breaks and continues. 2298 // Fake TOS for targets that shadowed breaks and continues.
2284 frame_->Push(Immediate(Factory::undefined_value())); 2299 frame_->Push(Immediate(Factory::undefined_value()));
2285 } 2300 }
2286 __ Set(ecx, Immediate(Smi::FromInt(JUMPING + i))); 2301 __ Set(ecx, Immediate(Smi::FromInt(JUMPING + i)));
2287 unlink.Jump(); 2302 unlink.Jump();
2288 } 2303 }
2289 } 2304 }
2290 2305
2291 // Unlink from try chain; be careful not to destroy the TOS. 2306 // Unlink from try chain; be careful not to destroy the TOS.
2292 unlink.Bind(); 2307 unlink.Bind();
2293 // Reload sp from the top handler, because some statements that we 2308 // Reload sp from the top handler, because some statements that we
(...skipping 29 matching lines...) Expand all
2323 // Generate code for the statements in the finally block. 2338 // Generate code for the statements in the finally block.
2324 VisitStatements(node->finally_block()->statements()); 2339 VisitStatements(node->finally_block()->statements());
2325 2340
2326 break_stack_height_ -= kFinallyStackSize; 2341 break_stack_height_ -= kFinallyStackSize;
2327 if (frame_ != NULL) { 2342 if (frame_ != NULL) {
2328 // Restore state and return value or faked TOS. 2343 // Restore state and return value or faked TOS.
2329 frame_->Pop(ecx); 2344 frame_->Pop(ecx);
2330 frame_->Pop(eax); 2345 frame_->Pop(eax);
2331 2346
2332 // Generate code to jump to the right destination for all used 2347 // Generate code to jump to the right destination for all used
2333 // (formerly) shadowing labels. 2348 // (formerly) shadowing targets.
2334 for (int i = 0; i <= nof_escapes; i++) { 2349 for (int i = 0; i <= nof_escapes; i++) {
2335 if (shadows[i]->is_bound()) { 2350 if (shadows[i]->is_bound()) {
2336 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); 2351 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i)));
2337 shadows[i]->original_target()->Branch(equal); 2352 shadows[i]->original_target()->Branch(equal);
2338 } 2353 }
2339 } 2354 }
2340 2355
2341 // Check if we need to rethrow the exception. 2356 // Check if we need to rethrow the exception.
2342 __ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING))); 2357 __ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING)));
2343 exit.Branch(not_equal); 2358 exit.Branch(not_equal);
(...skipping 2971 matching lines...) Expand 10 before | Expand all | Expand 10 after
5315 5330
5316 // Slow-case: Go through the JavaScript implementation. 5331 // Slow-case: Go through the JavaScript implementation.
5317 __ bind(&slow); 5332 __ bind(&slow);
5318 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5333 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5319 } 5334 }
5320 5335
5321 5336
5322 #undef __ 5337 #undef __
5323 5338
5324 } } // namespace v8::internal 5339 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-arm.cc ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698