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

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

Issue 6597029: [Isolates] Merge r 6300:6500 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: Created 9 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/arm/frames-arm.cc ('k') | src/arm/ic-arm.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 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 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 // Call the runtime to find the boolean value of the source and then 510 // Call the runtime to find the boolean value of the source and then
511 // translate it into control flow to the pair of labels. 511 // translate it into control flow to the pair of labels.
512 __ push(result_register()); 512 __ push(result_register());
513 __ CallRuntime(Runtime::kToBool, 1); 513 __ CallRuntime(Runtime::kToBool, 1);
514 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 514 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
515 __ cmp(r0, ip); 515 __ cmp(r0, ip);
516 Split(eq, if_true, if_false, fall_through); 516 Split(eq, if_true, if_false, fall_through);
517 } 517 }
518 518
519 519
520 void FullCodeGenerator::Split(Condition cc, 520 void FullCodeGenerator::Split(Condition cond,
521 Label* if_true, 521 Label* if_true,
522 Label* if_false, 522 Label* if_false,
523 Label* fall_through) { 523 Label* fall_through) {
524 if (if_false == fall_through) { 524 if (if_false == fall_through) {
525 __ b(cc, if_true); 525 __ b(cond, if_true);
526 } else if (if_true == fall_through) { 526 } else if (if_true == fall_through) {
527 __ b(NegateCondition(cc), if_false); 527 __ b(NegateCondition(cond), if_false);
528 } else { 528 } else {
529 __ b(cc, if_true); 529 __ b(cond, if_true);
530 __ b(if_false); 530 __ b(if_false);
531 } 531 }
532 } 532 }
533 533
534 534
535 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) { 535 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
536 switch (slot->type()) { 536 switch (slot->type()) {
537 case Slot::PARAMETER: 537 case Slot::PARAMETER:
538 case Slot::LOCAL: 538 case Slot::LOCAL:
539 return MemOperand(fp, SlotOffset(slot)); 539 return MemOperand(fp, SlotOffset(slot));
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 728
729 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 729 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
730 730
731 ZoneList<CaseClause*>* clauses = stmt->cases(); 731 ZoneList<CaseClause*>* clauses = stmt->cases();
732 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 732 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
733 733
734 Label next_test; // Recycled for each test. 734 Label next_test; // Recycled for each test.
735 // Compile all the tests with branches to their bodies. 735 // Compile all the tests with branches to their bodies.
736 for (int i = 0; i < clauses->length(); i++) { 736 for (int i = 0; i < clauses->length(); i++) {
737 CaseClause* clause = clauses->at(i); 737 CaseClause* clause = clauses->at(i);
738 clause->body_target()->entry_label()->Unuse();
739
738 // The default is not a test, but remember it as final fall through. 740 // The default is not a test, but remember it as final fall through.
739 if (clause->is_default()) { 741 if (clause->is_default()) {
740 default_clause = clause; 742 default_clause = clause;
741 continue; 743 continue;
742 } 744 }
743 745
744 Comment cmnt(masm_, "[ Case comparison"); 746 Comment cmnt(masm_, "[ Case comparison");
745 __ bind(&next_test); 747 __ bind(&next_test);
746 next_test.Unuse(); 748 next_test.Unuse();
747 749
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 VisitForAccumulatorValue(stmt->enumerable()); 813 VisitForAccumulatorValue(stmt->enumerable());
812 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 814 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
813 __ cmp(r0, ip); 815 __ cmp(r0, ip);
814 __ b(eq, &exit); 816 __ b(eq, &exit);
815 __ LoadRoot(ip, Heap::kNullValueRootIndex); 817 __ LoadRoot(ip, Heap::kNullValueRootIndex);
816 __ cmp(r0, ip); 818 __ cmp(r0, ip);
817 __ b(eq, &exit); 819 __ b(eq, &exit);
818 820
819 // Convert the object to a JS object. 821 // Convert the object to a JS object.
820 Label convert, done_convert; 822 Label convert, done_convert;
821 __ BranchOnSmi(r0, &convert); 823 __ JumpIfSmi(r0, &convert);
822 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); 824 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
823 __ b(hs, &done_convert); 825 __ b(hs, &done_convert);
824 __ bind(&convert); 826 __ bind(&convert);
825 __ push(r0); 827 __ push(r0);
826 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); 828 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
827 __ bind(&done_convert); 829 __ bind(&done_convert);
828 __ push(r0); 830 __ push(r0);
829 831
830 // BUG(867): Check cache validity in generated code. This is a fast 832 // BUG(867): Check cache validity in generated code. This is a fast
831 // case for the JSObject::IsSimpleEnum cache validity checks. If we 833 // case for the JSObject::IsSimpleEnum cache validity checks. If we
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 Expression* right, 1553 Expression* right,
1552 ConstantOperand constant) { 1554 ConstantOperand constant) {
1553 ASSERT(constant == kNoConstants); // Only handled case. 1555 ASSERT(constant == kNoConstants); // Only handled case.
1554 EmitBinaryOp(op, mode); 1556 EmitBinaryOp(op, mode);
1555 } 1557 }
1556 1558
1557 1559
1558 void FullCodeGenerator::EmitBinaryOp(Token::Value op, 1560 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1559 OverwriteMode mode) { 1561 OverwriteMode mode) {
1560 __ pop(r1); 1562 __ pop(r1);
1561 GenericBinaryOpStub stub(op, mode, r1, r0); 1563 if (op == Token::ADD || op == Token::SUB) {
1562 __ CallStub(&stub); 1564 TypeRecordingBinaryOpStub stub(op, mode);
1565 __ CallStub(&stub);
1566 } else {
1567 GenericBinaryOpStub stub(op, mode, r1, r0);
1568 __ CallStub(&stub);
1569 }
1563 context()->Plug(r0); 1570 context()->Plug(r0);
1564 } 1571 }
1565 1572
1566 1573
1567 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1574 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1568 // Invalid left-hand sides are rewritten to have a 'throw 1575 // Invalid left-hand sides are rewritten to have a 'throw
1569 // ReferenceError' on the left-hand side. 1576 // ReferenceError' on the left-hand side.
1570 if (!expr->IsValidLeftHandSide()) { 1577 if (!expr->IsValidLeftHandSide()) {
1571 VisitForEffect(expr); 1578 VisitForEffect(expr);
1572 return; 1579 return;
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1998 if (key != NULL && key->handle()->IsSymbol()) { 2005 if (key != NULL && key->handle()->IsSymbol()) {
1999 // Call to a named property, use call IC. 2006 // Call to a named property, use call IC.
2000 { PreservePositionScope scope(masm()->positions_recorder()); 2007 { PreservePositionScope scope(masm()->positions_recorder());
2001 VisitForStackValue(prop->obj()); 2008 VisitForStackValue(prop->obj());
2002 } 2009 }
2003 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2010 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2004 } else { 2011 } else {
2005 // Call to a keyed property. 2012 // Call to a keyed property.
2006 // For a synthetic property use keyed load IC followed by function call, 2013 // For a synthetic property use keyed load IC followed by function call,
2007 // for a regular property use keyed CallIC. 2014 // for a regular property use keyed CallIC.
2008 { PreservePositionScope scope(masm()->positions_recorder());
2009 VisitForStackValue(prop->obj());
2010 }
2011 if (prop->is_synthetic()) { 2015 if (prop->is_synthetic()) {
2012 { PreservePositionScope scope(masm()->positions_recorder()); 2016 // Do not visit the object and key subexpressions (they are shared
2013 VisitForAccumulatorValue(prop->key()); 2017 // by all occurrences of the same rewritten parameter).
2014 } 2018 ASSERT(prop->obj()->AsVariableProxy() != NULL);
2019 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL);
2020 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot();
2021 MemOperand operand = EmitSlotSearch(slot, r1);
2022 __ ldr(r1, operand);
2023
2024 ASSERT(prop->key()->AsLiteral() != NULL);
2025 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2026 __ mov(r0, Operand(prop->key()->AsLiteral()->handle()));
2027
2015 // Record source code position for IC call. 2028 // Record source code position for IC call.
2016 SetSourcePosition(prop->position()); 2029 SetSourcePosition(prop->position());
2017 __ pop(r1); // We do not need to keep the receiver.
2018 2030
2019 Handle<Code> ic(isolate()->builtins()->builtin( 2031 Handle<Code> ic(isolate()->builtins()->builtin(
2020 Builtins::KeyedLoadIC_Initialize)); 2032 Builtins::KeyedLoadIC_Initialize));
2021 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2033 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2022 __ ldr(r1, GlobalObjectOperand()); 2034 __ ldr(r1, GlobalObjectOperand());
2023 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 2035 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2024 __ Push(r0, r1); // Function, receiver. 2036 __ Push(r0, r1); // Function, receiver.
2025 EmitCallWithStub(expr); 2037 EmitCallWithStub(expr);
2026 } else { 2038 } else {
2039 { PreservePositionScope scope(masm()->positions_recorder());
2040 VisitForStackValue(prop->obj());
2041 }
2027 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2042 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2028 } 2043 }
2029 } 2044 }
2030 } else { 2045 } else {
2031 // Call to some other expression. If the expression is an anonymous 2046 // Call to some other expression. If the expression is an anonymous
2032 // function literal not called in a loop, mark it as one that should 2047 // function literal not called in a loop, mark it as one that should
2033 // also use the fast code generator. 2048 // also use the fast code generator.
2034 FunctionLiteral* lit = fun->AsFunctionLiteral(); 2049 FunctionLiteral* lit = fun->AsFunctionLiteral();
2035 if (lit != NULL && 2050 if (lit != NULL &&
2036 lit->name()->Equals(isolate()->heap()->empty_string()) && 2051 lit->name()->Equals(isolate()->heap()->empty_string()) &&
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 2149
2135 VisitForAccumulatorValue(args->at(0)); 2150 VisitForAccumulatorValue(args->at(0));
2136 2151
2137 Label materialize_true, materialize_false; 2152 Label materialize_true, materialize_false;
2138 Label* if_true = NULL; 2153 Label* if_true = NULL;
2139 Label* if_false = NULL; 2154 Label* if_false = NULL;
2140 Label* fall_through = NULL; 2155 Label* fall_through = NULL;
2141 context()->PrepareTest(&materialize_true, &materialize_false, 2156 context()->PrepareTest(&materialize_true, &materialize_false,
2142 &if_true, &if_false, &fall_through); 2157 &if_true, &if_false, &fall_through);
2143 2158
2144 __ BranchOnSmi(r0, if_false); 2159 __ JumpIfSmi(r0, if_false);
2145 __ LoadRoot(ip, Heap::kNullValueRootIndex); 2160 __ LoadRoot(ip, Heap::kNullValueRootIndex);
2146 __ cmp(r0, ip); 2161 __ cmp(r0, ip);
2147 __ b(eq, if_true); 2162 __ b(eq, if_true);
2148 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 2163 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
2149 // Undetectable objects behave like undefined when tested with typeof. 2164 // Undetectable objects behave like undefined when tested with typeof.
2150 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); 2165 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset));
2151 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 2166 __ tst(r1, Operand(1 << Map::kIsUndetectable));
2152 __ b(ne, if_false); 2167 __ b(ne, if_false);
2153 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 2168 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset));
2154 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); 2169 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
(...skipping 11 matching lines...) Expand all
2166 2181
2167 VisitForAccumulatorValue(args->at(0)); 2182 VisitForAccumulatorValue(args->at(0));
2168 2183
2169 Label materialize_true, materialize_false; 2184 Label materialize_true, materialize_false;
2170 Label* if_true = NULL; 2185 Label* if_true = NULL;
2171 Label* if_false = NULL; 2186 Label* if_false = NULL;
2172 Label* fall_through = NULL; 2187 Label* fall_through = NULL;
2173 context()->PrepareTest(&materialize_true, &materialize_false, 2188 context()->PrepareTest(&materialize_true, &materialize_false,
2174 &if_true, &if_false, &fall_through); 2189 &if_true, &if_false, &fall_through);
2175 2190
2176 __ BranchOnSmi(r0, if_false); 2191 __ JumpIfSmi(r0, if_false);
2177 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); 2192 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
2178 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2193 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2179 Split(ge, if_true, if_false, fall_through); 2194 Split(ge, if_true, if_false, fall_through);
2180 2195
2181 context()->Plug(if_true, if_false); 2196 context()->Plug(if_true, if_false);
2182 } 2197 }
2183 2198
2184 2199
2185 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { 2200 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
2186 ASSERT(args->length() == 1); 2201 ASSERT(args->length() == 1);
2187 2202
2188 VisitForAccumulatorValue(args->at(0)); 2203 VisitForAccumulatorValue(args->at(0));
2189 2204
2190 Label materialize_true, materialize_false; 2205 Label materialize_true, materialize_false;
2191 Label* if_true = NULL; 2206 Label* if_true = NULL;
2192 Label* if_false = NULL; 2207 Label* if_false = NULL;
2193 Label* fall_through = NULL; 2208 Label* fall_through = NULL;
2194 context()->PrepareTest(&materialize_true, &materialize_false, 2209 context()->PrepareTest(&materialize_true, &materialize_false,
2195 &if_true, &if_false, &fall_through); 2210 &if_true, &if_false, &fall_through);
2196 2211
2197 __ BranchOnSmi(r0, if_false); 2212 __ JumpIfSmi(r0, if_false);
2198 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 2213 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
2199 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); 2214 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
2200 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 2215 __ tst(r1, Operand(1 << Map::kIsUndetectable));
2201 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2216 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2202 Split(ne, if_true, if_false, fall_through); 2217 Split(ne, if_true, if_false, fall_through);
2203 2218
2204 context()->Plug(if_true, if_false); 2219 context()->Plug(if_true, if_false);
2205 } 2220 }
2206 2221
2207 2222
(...skipping 25 matching lines...) Expand all
2233 2248
2234 VisitForAccumulatorValue(args->at(0)); 2249 VisitForAccumulatorValue(args->at(0));
2235 2250
2236 Label materialize_true, materialize_false; 2251 Label materialize_true, materialize_false;
2237 Label* if_true = NULL; 2252 Label* if_true = NULL;
2238 Label* if_false = NULL; 2253 Label* if_false = NULL;
2239 Label* fall_through = NULL; 2254 Label* fall_through = NULL;
2240 context()->PrepareTest(&materialize_true, &materialize_false, 2255 context()->PrepareTest(&materialize_true, &materialize_false,
2241 &if_true, &if_false, &fall_through); 2256 &if_true, &if_false, &fall_through);
2242 2257
2243 __ BranchOnSmi(r0, if_false); 2258 __ JumpIfSmi(r0, if_false);
2244 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); 2259 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
2245 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2260 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2246 Split(eq, if_true, if_false, fall_through); 2261 Split(eq, if_true, if_false, fall_through);
2247 2262
2248 context()->Plug(if_true, if_false); 2263 context()->Plug(if_true, if_false);
2249 } 2264 }
2250 2265
2251 2266
2252 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { 2267 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
2253 ASSERT(args->length() == 1); 2268 ASSERT(args->length() == 1);
2254 2269
2255 VisitForAccumulatorValue(args->at(0)); 2270 VisitForAccumulatorValue(args->at(0));
2256 2271
2257 Label materialize_true, materialize_false; 2272 Label materialize_true, materialize_false;
2258 Label* if_true = NULL; 2273 Label* if_true = NULL;
2259 Label* if_false = NULL; 2274 Label* if_false = NULL;
2260 Label* fall_through = NULL; 2275 Label* fall_through = NULL;
2261 context()->PrepareTest(&materialize_true, &materialize_false, 2276 context()->PrepareTest(&materialize_true, &materialize_false,
2262 &if_true, &if_false, &fall_through); 2277 &if_true, &if_false, &fall_through);
2263 2278
2264 __ BranchOnSmi(r0, if_false); 2279 __ JumpIfSmi(r0, if_false);
2265 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); 2280 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
2266 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2281 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2267 Split(eq, if_true, if_false, fall_through); 2282 Split(eq, if_true, if_false, fall_through);
2268 2283
2269 context()->Plug(if_true, if_false); 2284 context()->Plug(if_true, if_false);
2270 } 2285 }
2271 2286
2272 2287
2273 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { 2288 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
2274 ASSERT(args->length() == 1); 2289 ASSERT(args->length() == 1);
2275 2290
2276 VisitForAccumulatorValue(args->at(0)); 2291 VisitForAccumulatorValue(args->at(0));
2277 2292
2278 Label materialize_true, materialize_false; 2293 Label materialize_true, materialize_false;
2279 Label* if_true = NULL; 2294 Label* if_true = NULL;
2280 Label* if_false = NULL; 2295 Label* if_false = NULL;
2281 Label* fall_through = NULL; 2296 Label* fall_through = NULL;
2282 context()->PrepareTest(&materialize_true, &materialize_false, 2297 context()->PrepareTest(&materialize_true, &materialize_false,
2283 &if_true, &if_false, &fall_through); 2298 &if_true, &if_false, &fall_through);
2284 2299
2285 __ BranchOnSmi(r0, if_false); 2300 __ JumpIfSmi(r0, if_false);
2286 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); 2301 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
2287 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2302 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2288 Split(eq, if_true, if_false, fall_through); 2303 Split(eq, if_true, if_false, fall_through);
2289 2304
2290 context()->Plug(if_true, if_false); 2305 context()->Plug(if_true, if_false);
2291 } 2306 }
2292 2307
2293 2308
2294 2309
2295 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { 2310 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2382 } 2397 }
2383 2398
2384 2399
2385 void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { 2400 void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
2386 ASSERT(args->length() == 1); 2401 ASSERT(args->length() == 1);
2387 Label done, null, function, non_function_constructor; 2402 Label done, null, function, non_function_constructor;
2388 2403
2389 VisitForAccumulatorValue(args->at(0)); 2404 VisitForAccumulatorValue(args->at(0));
2390 2405
2391 // If the object is a smi, we return null. 2406 // If the object is a smi, we return null.
2392 __ BranchOnSmi(r0, &null); 2407 __ JumpIfSmi(r0, &null);
2393 2408
2394 // Check that the object is a JS object but take special care of JS 2409 // Check that the object is a JS object but take special care of JS
2395 // functions to make sure they have 'Function' as their class. 2410 // functions to make sure they have 'Function' as their class.
2396 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); // Map is now in r0. 2411 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); // Map is now in r0.
2397 __ b(lt, &null); 2412 __ b(lt, &null);
2398 2413
2399 // As long as JS_FUNCTION_TYPE is the last instance type and it is 2414 // As long as JS_FUNCTION_TYPE is the last instance type and it is
2400 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for 2415 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
2401 // LAST_JS_OBJECT_TYPE. 2416 // LAST_JS_OBJECT_TYPE.
2402 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 2417 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2533 } 2548 }
2534 2549
2535 2550
2536 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { 2551 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
2537 ASSERT(args->length() == 1); 2552 ASSERT(args->length() == 1);
2538 2553
2539 VisitForAccumulatorValue(args->at(0)); // Load the object. 2554 VisitForAccumulatorValue(args->at(0)); // Load the object.
2540 2555
2541 Label done; 2556 Label done;
2542 // If the object is a smi return the object. 2557 // If the object is a smi return the object.
2543 __ BranchOnSmi(r0, &done); 2558 __ JumpIfSmi(r0, &done);
2544 // If the object is not a value type, return the object. 2559 // If the object is not a value type, return the object.
2545 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); 2560 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE);
2546 __ b(ne, &done); 2561 __ b(ne, &done);
2547 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); 2562 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset));
2548 2563
2549 __ bind(&done); 2564 __ bind(&done);
2550 context()->Plug(r0); 2565 context()->Plug(r0);
2551 } 2566 }
2552 2567
2553 2568
2554 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { 2569 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
2555 // Load the arguments on the stack and call the runtime function. 2570 // Load the arguments on the stack and call the runtime function.
2556 ASSERT(args->length() == 2); 2571 ASSERT(args->length() == 2);
2557 VisitForStackValue(args->at(0)); 2572 VisitForStackValue(args->at(0));
2558 VisitForStackValue(args->at(1)); 2573 VisitForStackValue(args->at(1));
2559 __ CallRuntime(Runtime::kMath_pow, 2); 2574 __ CallRuntime(Runtime::kMath_pow, 2);
2560 context()->Plug(r0); 2575 context()->Plug(r0);
2561 } 2576 }
2562 2577
2563 2578
2564 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2579 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
2565 ASSERT(args->length() == 2); 2580 ASSERT(args->length() == 2);
2566 2581
2567 VisitForStackValue(args->at(0)); // Load the object. 2582 VisitForStackValue(args->at(0)); // Load the object.
2568 VisitForAccumulatorValue(args->at(1)); // Load the value. 2583 VisitForAccumulatorValue(args->at(1)); // Load the value.
2569 __ pop(r1); // r0 = value. r1 = object. 2584 __ pop(r1); // r0 = value. r1 = object.
2570 2585
2571 Label done; 2586 Label done;
2572 // If the object is a smi, return the value. 2587 // If the object is a smi, return the value.
2573 __ BranchOnSmi(r1, &done); 2588 __ JumpIfSmi(r1, &done);
2574 2589
2575 // If the object is not a value type, return the value. 2590 // If the object is not a value type, return the value.
2576 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); 2591 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE);
2577 __ b(ne, &done); 2592 __ b(ne, &done);
2578 2593
2579 // Store the value. 2594 // Store the value.
2580 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); 2595 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset));
2581 // Update the write barrier. Save the value as it will be 2596 // Update the write barrier. Save the value as it will be
2582 // overwritten by the write barrier code and is needed afterward. 2597 // overwritten by the write barrier code and is needed afterward.
2583 __ RecordWrite(r1, Operand(JSValue::kValueOffset - kHeapObjectTag), r2, r3); 2598 __ RecordWrite(r1, Operand(JSValue::kValueOffset - kHeapObjectTag), r2, r3);
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
2997 var->AsSlot()->type() != Slot::LOOKUP) { 3012 var->AsSlot()->type() != Slot::LOOKUP) {
2998 // Result of deleting non-global, non-dynamic variables is false. 3013 // Result of deleting non-global, non-dynamic variables is false.
2999 // The subexpression does not have side effects. 3014 // The subexpression does not have side effects.
3000 context()->Plug(false); 3015 context()->Plug(false);
3001 } else { 3016 } else {
3002 // Property or variable reference. Call the delete builtin with 3017 // Property or variable reference. Call the delete builtin with
3003 // object and property name as arguments. 3018 // object and property name as arguments.
3004 if (prop != NULL) { 3019 if (prop != NULL) {
3005 VisitForStackValue(prop->obj()); 3020 VisitForStackValue(prop->obj());
3006 VisitForStackValue(prop->key()); 3021 VisitForStackValue(prop->key());
3022 __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
3007 } else if (var->is_global()) { 3023 } else if (var->is_global()) {
3008 __ ldr(r1, GlobalObjectOperand()); 3024 __ ldr(r1, GlobalObjectOperand());
3009 __ mov(r0, Operand(var->name())); 3025 __ mov(r0, Operand(var->name()));
3010 __ Push(r1, r0); 3026 __ Push(r1, r0);
3027 __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
3011 } else { 3028 } else {
3012 // Non-global variable. Call the runtime to look up the context 3029 // Non-global variable. Call the runtime to delete from the
3013 // where the variable was introduced. 3030 // context where the variable was introduced.
3014 __ push(context_register()); 3031 __ push(context_register());
3015 __ mov(r2, Operand(var->name())); 3032 __ mov(r2, Operand(var->name()));
3016 __ push(r2); 3033 __ push(r2);
3017 __ CallRuntime(Runtime::kLookupContext, 2); 3034 __ CallRuntime(Runtime::kDeleteContextSlot, 2);
3018 __ push(r0);
3019 __ mov(r2, Operand(var->name()));
3020 __ push(r2);
3021 } 3035 }
3022 __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
3023 context()->Plug(r0); 3036 context()->Plug(r0);
3024 } 3037 }
3025 break; 3038 break;
3026 } 3039 }
3027 3040
3028 case Token::VOID: { 3041 case Token::VOID: {
3029 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 3042 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
3030 VisitForEffect(expr->expression()); 3043 VisitForEffect(expr->expression());
3031 context()->Plug(Heap::kUndefinedValueRootIndex); 3044 context()->Plug(Heap::kUndefinedValueRootIndex);
3032 break; 3045 break;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3089 3102
3090 case Token::BIT_NOT: { 3103 case Token::BIT_NOT: {
3091 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); 3104 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
3092 // The generic unary operation stub expects the argument to be 3105 // The generic unary operation stub expects the argument to be
3093 // in the accumulator register r0. 3106 // in the accumulator register r0.
3094 VisitForAccumulatorValue(expr->expression()); 3107 VisitForAccumulatorValue(expr->expression());
3095 Label done; 3108 Label done;
3096 bool inline_smi_code = ShouldInlineSmiCase(expr->op()); 3109 bool inline_smi_code = ShouldInlineSmiCase(expr->op());
3097 if (inline_smi_code) { 3110 if (inline_smi_code) {
3098 Label call_stub; 3111 Label call_stub;
3099 __ BranchOnNotSmi(r0, &call_stub); 3112 __ JumpIfNotSmi(r0, &call_stub);
3100 __ mvn(r0, Operand(r0)); 3113 __ mvn(r0, Operand(r0));
3101 // Bit-clear inverted smi-tag. 3114 // Bit-clear inverted smi-tag.
3102 __ bic(r0, r0, Operand(kSmiTagMask)); 3115 __ bic(r0, r0, Operand(kSmiTagMask));
3103 __ b(&done); 3116 __ b(&done);
3104 __ bind(&call_stub); 3117 __ bind(&call_stub);
3105 } 3118 }
3106 bool overwrite = expr->expression()->ResultOverwriteAllowed(); 3119 bool overwrite = expr->expression()->ResultOverwriteAllowed();
3107 UnaryOpFlags flags = inline_smi_code 3120 UnaryOpFlags flags = inline_smi_code
3108 ? NO_UNARY_SMI_CODE_IN_STUB 3121 ? NO_UNARY_SMI_CODE_IN_STUB
3109 : NO_UNARY_FLAGS; 3122 : NO_UNARY_FLAGS;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3176 EmitKeyedPropertyLoad(prop); 3189 EmitKeyedPropertyLoad(prop);
3177 } 3190 }
3178 } 3191 }
3179 3192
3180 // We need a second deoptimization point after loading the value 3193 // We need a second deoptimization point after loading the value
3181 // in case evaluating the property load my have a side effect. 3194 // in case evaluating the property load my have a side effect.
3182 PrepareForBailout(expr->increment(), TOS_REG); 3195 PrepareForBailout(expr->increment(), TOS_REG);
3183 3196
3184 // Call ToNumber only if operand is not a smi. 3197 // Call ToNumber only if operand is not a smi.
3185 Label no_conversion; 3198 Label no_conversion;
3186 __ BranchOnSmi(r0, &no_conversion); 3199 __ JumpIfSmi(r0, &no_conversion);
3187 __ push(r0); 3200 __ push(r0);
3188 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); 3201 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS);
3189 __ bind(&no_conversion); 3202 __ bind(&no_conversion);
3190 3203
3191 // Save result for postfix expressions. 3204 // Save result for postfix expressions.
3192 if (expr->is_postfix()) { 3205 if (expr->is_postfix()) {
3193 if (!context()->IsEffect()) { 3206 if (!context()->IsEffect()) {
3194 // Save the result on the stack. If we have a named or keyed property 3207 // Save the result on the stack. If we have a named or keyed property
3195 // we store the result under the receiver that is currently on top 3208 // we store the result under the receiver that is currently on top
3196 // of the stack. 3209 // of the stack.
(...skipping 13 matching lines...) Expand all
3210 3223
3211 3224
3212 // Inline smi case if we are in a loop. 3225 // Inline smi case if we are in a loop.
3213 Label stub_call, done; 3226 Label stub_call, done;
3214 int count_value = expr->op() == Token::INC ? 1 : -1; 3227 int count_value = expr->op() == Token::INC ? 1 : -1;
3215 if (ShouldInlineSmiCase(expr->op())) { 3228 if (ShouldInlineSmiCase(expr->op())) {
3216 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); 3229 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC);
3217 __ b(vs, &stub_call); 3230 __ b(vs, &stub_call);
3218 // We could eliminate this smi check if we split the code at 3231 // We could eliminate this smi check if we split the code at
3219 // the first smi check before calling ToNumber. 3232 // the first smi check before calling ToNumber.
3220 __ BranchOnSmi(r0, &done); 3233 __ JumpIfSmi(r0, &done);
3221 __ bind(&stub_call); 3234 __ bind(&stub_call);
3222 // Call stub. Undo operation first. 3235 // Call stub. Undo operation first.
3223 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); 3236 __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
3224 } 3237 }
3225 __ mov(r1, Operand(Smi::FromInt(count_value))); 3238 __ mov(r1, Operand(Smi::FromInt(count_value)));
3226 3239
3227 // Record position before stub call. 3240 // Record position before stub call.
3228 SetSourcePosition(expr->position()); 3241 SetSourcePosition(expr->position());
3229 3242
3230 GenericBinaryOpStub stub(Token::ADD, NO_OVERWRITE, r1, r0); 3243 GenericBinaryOpStub stub(Token::ADD, NO_OVERWRITE, r1, r0);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
3466 __ CallStub(&stub); 3479 __ CallStub(&stub);
3467 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3480 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3468 // The stub returns 0 for true. 3481 // The stub returns 0 for true.
3469 __ tst(r0, r0); 3482 __ tst(r0, r0);
3470 Split(eq, if_true, if_false, fall_through); 3483 Split(eq, if_true, if_false, fall_through);
3471 break; 3484 break;
3472 } 3485 }
3473 3486
3474 default: { 3487 default: {
3475 VisitForAccumulatorValue(expr->right()); 3488 VisitForAccumulatorValue(expr->right());
3476 Condition cc = eq; 3489 Condition cond = eq;
3477 bool strict = false; 3490 bool strict = false;
3478 switch (op) { 3491 switch (op) {
3479 case Token::EQ_STRICT: 3492 case Token::EQ_STRICT:
3480 strict = true; 3493 strict = true;
3481 // Fall through 3494 // Fall through
3482 case Token::EQ: 3495 case Token::EQ:
3483 cc = eq; 3496 cond = eq;
3484 __ pop(r1); 3497 __ pop(r1);
3485 break; 3498 break;
3486 case Token::LT: 3499 case Token::LT:
3487 cc = lt; 3500 cond = lt;
3488 __ pop(r1); 3501 __ pop(r1);
3489 break; 3502 break;
3490 case Token::GT: 3503 case Token::GT:
3491 // Reverse left and right sides to obtain ECMA-262 conversion order. 3504 // Reverse left and right sides to obtain ECMA-262 conversion order.
3492 cc = lt; 3505 cond = lt;
3493 __ mov(r1, result_register()); 3506 __ mov(r1, result_register());
3494 __ pop(r0); 3507 __ pop(r0);
3495 break; 3508 break;
3496 case Token::LTE: 3509 case Token::LTE:
3497 // Reverse left and right sides to obtain ECMA-262 conversion order. 3510 // Reverse left and right sides to obtain ECMA-262 conversion order.
3498 cc = ge; 3511 cond = ge;
3499 __ mov(r1, result_register()); 3512 __ mov(r1, result_register());
3500 __ pop(r0); 3513 __ pop(r0);
3501 break; 3514 break;
3502 case Token::GTE: 3515 case Token::GTE:
3503 cc = ge; 3516 cond = ge;
3504 __ pop(r1); 3517 __ pop(r1);
3505 break; 3518 break;
3506 case Token::IN: 3519 case Token::IN:
3507 case Token::INSTANCEOF: 3520 case Token::INSTANCEOF:
3508 default: 3521 default:
3509 UNREACHABLE(); 3522 UNREACHABLE();
3510 } 3523 }
3511 3524
3512 bool inline_smi_code = ShouldInlineSmiCase(op); 3525 bool inline_smi_code = ShouldInlineSmiCase(op);
3513 if (inline_smi_code) { 3526 if (inline_smi_code) {
3514 Label slow_case; 3527 Label slow_case;
3515 __ orr(r2, r0, Operand(r1)); 3528 __ orr(r2, r0, Operand(r1));
3516 __ BranchOnNotSmi(r2, &slow_case); 3529 __ JumpIfNotSmi(r2, &slow_case);
3517 __ cmp(r1, r0); 3530 __ cmp(r1, r0);
3518 Split(cc, if_true, if_false, NULL); 3531 Split(cond, if_true, if_false, NULL);
3519 __ bind(&slow_case); 3532 __ bind(&slow_case);
3520 } 3533 }
3521 CompareFlags flags = inline_smi_code 3534 CompareFlags flags = inline_smi_code
3522 ? NO_SMI_COMPARE_IN_STUB 3535 ? NO_SMI_COMPARE_IN_STUB
3523 : NO_COMPARE_FLAGS; 3536 : NO_COMPARE_FLAGS;
3524 CompareStub stub(cc, strict, flags, r1, r0); 3537 CompareStub stub(cond, strict, flags, r1, r0);
3525 __ CallStub(&stub); 3538 __ CallStub(&stub);
3526 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3539 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3527 __ cmp(r0, Operand(0, RelocInfo::NONE)); 3540 __ cmp(r0, Operand(0, RelocInfo::NONE));
3528 Split(cc, if_true, if_false, fall_through); 3541 Split(cond, if_true, if_false, fall_through);
3529 } 3542 }
3530 } 3543 }
3531 3544
3532 // Convert the result of the comparison into one expected for this 3545 // Convert the result of the comparison into one expected for this
3533 // expression's context. 3546 // expression's context.
3534 context()->Plug(if_true, if_false); 3547 context()->Plug(if_true, if_false);
3535 } 3548 }
3536 3549
3537 3550
3538 void FullCodeGenerator::VisitCompareToNull(CompareToNull* expr) { 3551 void FullCodeGenerator::VisitCompareToNull(CompareToNull* expr) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3628 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3641 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
3629 __ add(pc, r1, Operand(masm_->CodeObject())); 3642 __ add(pc, r1, Operand(masm_->CodeObject()));
3630 } 3643 }
3631 3644
3632 3645
3633 #undef __ 3646 #undef __
3634 3647
3635 } } // namespace v8::internal 3648 } } // namespace v8::internal
3636 3649
3637 #endif // V8_TARGET_ARCH_ARM 3650 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/frames-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698