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

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

Issue 6588047: Version 3.1.7... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
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/code-stubs-arm.cc ('k') | src/arm/lithium-codegen-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 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 if (true_label_ != fall_through_) __ b(true_label_); 567 if (true_label_ != fall_through_) __ b(true_label_);
568 } else { 568 } else {
569 if (false_label_ != fall_through_) __ b(false_label_); 569 if (false_label_ != fall_through_) __ b(false_label_);
570 } 570 }
571 } 571 }
572 572
573 573
574 void FullCodeGenerator::DoTest(Label* if_true, 574 void FullCodeGenerator::DoTest(Label* if_true,
575 Label* if_false, 575 Label* if_false,
576 Label* fall_through) { 576 Label* fall_through) {
577 // Call the runtime to find the boolean value of the source and then 577 if (CpuFeatures::IsSupported(VFP3)) {
578 // translate it into control flow to the pair of labels. 578 CpuFeatures::Scope scope(VFP3);
579 __ push(result_register()); 579 // Emit the inlined tests assumed by the stub.
580 __ CallRuntime(Runtime::kToBool, 1); 580 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
581 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 581 __ cmp(result_register(), ip);
582 __ cmp(r0, ip); 582 __ b(eq, if_false);
583 Split(eq, if_true, if_false, fall_through); 583 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
584 __ cmp(result_register(), ip);
585 __ b(eq, if_true);
586 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
587 __ cmp(result_register(), ip);
588 __ b(eq, if_false);
589 STATIC_ASSERT(kSmiTag == 0);
590 __ tst(result_register(), result_register());
591 __ b(eq, if_false);
592 __ JumpIfSmi(result_register(), if_true);
593
594 // Call the ToBoolean stub for all other cases.
595 ToBooleanStub stub(result_register());
596 __ CallStub(&stub);
597 __ tst(result_register(), result_register());
598 } else {
599 // Call the runtime to find the boolean value of the source and then
600 // translate it into control flow to the pair of labels.
601 __ push(result_register());
602 __ CallRuntime(Runtime::kToBool, 1);
603 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
604 __ cmp(r0, ip);
605 }
606
607 // The stub returns nonzero for true.
608 Split(ne, if_true, if_false, fall_through);
584 } 609 }
585 610
586 611
587 void FullCodeGenerator::Split(Condition cond, 612 void FullCodeGenerator::Split(Condition cond,
588 Label* if_true, 613 Label* if_true,
589 Label* if_false, 614 Label* if_false,
590 Label* fall_through) { 615 Label* fall_through) {
591 if (if_false == fall_through) { 616 if (if_false == fall_through) {
592 __ b(cond, if_true); 617 __ b(cond, if_true);
593 } else if (if_true == fall_through) { 618 } else if (if_true == fall_through) {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 __ Push(cp, r1, r0); 814 __ Push(cp, r1, r0);
790 __ CallRuntime(Runtime::kDeclareGlobals, 3); 815 __ CallRuntime(Runtime::kDeclareGlobals, 3);
791 // Return value is ignored. 816 // Return value is ignored.
792 } 817 }
793 818
794 819
795 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 820 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
796 Comment cmnt(masm_, "[ SwitchStatement"); 821 Comment cmnt(masm_, "[ SwitchStatement");
797 Breakable nested_statement(this, stmt); 822 Breakable nested_statement(this, stmt);
798 SetStatementPosition(stmt); 823 SetStatementPosition(stmt);
824
799 // Keep the switch value on the stack until a case matches. 825 // Keep the switch value on the stack until a case matches.
800 VisitForStackValue(stmt->tag()); 826 VisitForStackValue(stmt->tag());
801
802 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 827 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
803 828
804 ZoneList<CaseClause*>* clauses = stmt->cases(); 829 ZoneList<CaseClause*>* clauses = stmt->cases();
805 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 830 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
806 831
807 Label next_test; // Recycled for each test. 832 Label next_test; // Recycled for each test.
808 // Compile all the tests with branches to their bodies. 833 // Compile all the tests with branches to their bodies.
809 for (int i = 0; i < clauses->length(); i++) { 834 for (int i = 0; i < clauses->length(); i++) {
810 CaseClause* clause = clauses->at(i); 835 CaseClause* clause = clauses->at(i);
811 clause->body_target()->entry_label()->Unuse(); 836 clause->body_target()->entry_label()->Unuse();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 ForIn loop_statement(this, stmt); 905 ForIn loop_statement(this, stmt);
881 increment_loop_depth(); 906 increment_loop_depth();
882 907
883 // Get the object to enumerate over. Both SpiderMonkey and JSC 908 // Get the object to enumerate over. Both SpiderMonkey and JSC
884 // ignore null and undefined in contrast to the specification; see 909 // ignore null and undefined in contrast to the specification; see
885 // ECMA-262 section 12.6.4. 910 // ECMA-262 section 12.6.4.
886 VisitForAccumulatorValue(stmt->enumerable()); 911 VisitForAccumulatorValue(stmt->enumerable());
887 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 912 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
888 __ cmp(r0, ip); 913 __ cmp(r0, ip);
889 __ b(eq, &exit); 914 __ b(eq, &exit);
890 __ LoadRoot(ip, Heap::kNullValueRootIndex); 915 Register null_value = r5;
891 __ cmp(r0, ip); 916 __ LoadRoot(null_value, Heap::kNullValueRootIndex);
917 __ cmp(r0, null_value);
892 __ b(eq, &exit); 918 __ b(eq, &exit);
893 919
894 // Convert the object to a JS object. 920 // Convert the object to a JS object.
895 Label convert, done_convert; 921 Label convert, done_convert;
896 __ JumpIfSmi(r0, &convert); 922 __ JumpIfSmi(r0, &convert);
897 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); 923 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
898 __ b(hs, &done_convert); 924 __ b(hs, &done_convert);
899 __ bind(&convert); 925 __ bind(&convert);
900 __ push(r0); 926 __ push(r0);
901 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); 927 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
902 __ bind(&done_convert); 928 __ bind(&done_convert);
903 __ push(r0); 929 __ push(r0);
904 930
905 // BUG(867): Check cache validity in generated code. This is a fast 931 // Check cache validity in generated code. This is a fast case for
906 // case for the JSObject::IsSimpleEnum cache validity checks. If we 932 // the JSObject::IsSimpleEnum cache validity checks. If we cannot
907 // cannot guarantee cache validity, call the runtime system to check 933 // guarantee cache validity, call the runtime system to check cache
908 // cache validity or get the property names in a fixed array. 934 // validity or get the property names in a fixed array.
935 Label next, call_runtime;
936 // Preload a couple of values used in the loop.
937 Register empty_fixed_array_value = r6;
938 __ LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
939 Register empty_descriptor_array_value = r7;
940 __ LoadRoot(empty_descriptor_array_value,
941 Heap::kEmptyDescriptorArrayRootIndex);
942 __ mov(r1, r0);
943 __ bind(&next);
944
945 // Check that there are no elements. Register r1 contains the
946 // current JS object we've reached through the prototype chain.
947 __ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset));
948 __ cmp(r2, empty_fixed_array_value);
949 __ b(ne, &call_runtime);
950
951 // Check that instance descriptors are not empty so that we can
952 // check for an enum cache. Leave the map in r2 for the subsequent
953 // prototype load.
954 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
955 __ ldr(r3, FieldMemOperand(r2, Map::kInstanceDescriptorsOffset));
956 __ cmp(r3, empty_descriptor_array_value);
957 __ b(eq, &call_runtime);
958
959 // Check that there is an enum cache in the non-empty instance
960 // descriptors (r3). This is the case if the next enumeration
961 // index field does not contain a smi.
962 __ ldr(r3, FieldMemOperand(r3, DescriptorArray::kEnumerationIndexOffset));
963 __ JumpIfSmi(r3, &call_runtime);
964
965 // For all objects but the receiver, check that the cache is empty.
966 Label check_prototype;
967 __ cmp(r1, r0);
968 __ b(eq, &check_prototype);
969 __ ldr(r3, FieldMemOperand(r3, DescriptorArray::kEnumCacheBridgeCacheOffset));
970 __ cmp(r3, empty_fixed_array_value);
971 __ b(ne, &call_runtime);
972
973 // Load the prototype from the map and loop if non-null.
974 __ bind(&check_prototype);
975 __ ldr(r1, FieldMemOperand(r2, Map::kPrototypeOffset));
976 __ cmp(r1, null_value);
977 __ b(ne, &next);
978
979 // The enum cache is valid. Load the map of the object being
980 // iterated over and use the cache for the iteration.
981 Label use_cache;
982 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
983 __ b(&use_cache);
909 984
910 // Get the set of properties to enumerate. 985 // Get the set of properties to enumerate.
986 __ bind(&call_runtime);
911 __ push(r0); // Duplicate the enumerable object on the stack. 987 __ push(r0); // Duplicate the enumerable object on the stack.
912 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 988 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
913 989
914 // If we got a map from the runtime call, we can do a fast 990 // If we got a map from the runtime call, we can do a fast
915 // modification check. Otherwise, we got a fixed array, and we have 991 // modification check. Otherwise, we got a fixed array, and we have
916 // to do a slow check. 992 // to do a slow check.
917 Label fixed_array; 993 Label fixed_array;
918 __ mov(r2, r0); 994 __ mov(r2, r0);
919 __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); 995 __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
920 __ LoadRoot(ip, Heap::kMetaMapRootIndex); 996 __ LoadRoot(ip, Heap::kMetaMapRootIndex);
921 __ cmp(r1, ip); 997 __ cmp(r1, ip);
922 __ b(ne, &fixed_array); 998 __ b(ne, &fixed_array);
923 999
924 // We got a map in register r0. Get the enumeration cache from it. 1000 // We got a map in register r0. Get the enumeration cache from it.
1001 __ bind(&use_cache);
925 __ ldr(r1, FieldMemOperand(r0, Map::kInstanceDescriptorsOffset)); 1002 __ ldr(r1, FieldMemOperand(r0, Map::kInstanceDescriptorsOffset));
926 __ ldr(r1, FieldMemOperand(r1, DescriptorArray::kEnumerationIndexOffset)); 1003 __ ldr(r1, FieldMemOperand(r1, DescriptorArray::kEnumerationIndexOffset));
927 __ ldr(r2, FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset)); 1004 __ ldr(r2, FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset));
928 1005
929 // Setup the four remaining stack slots. 1006 // Setup the four remaining stack slots.
930 __ push(r0); // Map. 1007 __ push(r0); // Map.
931 __ ldr(r1, FieldMemOperand(r2, FixedArray::kLengthOffset)); 1008 __ ldr(r1, FieldMemOperand(r2, FixedArray::kLengthOffset));
932 __ mov(r0, Operand(Smi::FromInt(0))); 1009 __ mov(r0, Operand(Smi::FromInt(0)));
933 // Push enumeration cache, enumeration cache length (as smi) and zero. 1010 // Push enumeration cache, enumeration cache length (as smi) and zero.
934 __ Push(r2, r1, r0); 1011 __ Push(r2, r1, r0);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 1080
1004 // Exit and decrement the loop depth. 1081 // Exit and decrement the loop depth.
1005 __ bind(&exit); 1082 __ bind(&exit);
1006 decrement_loop_depth(); 1083 decrement_loop_depth();
1007 } 1084 }
1008 1085
1009 1086
1010 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1087 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1011 bool pretenure) { 1088 bool pretenure) {
1012 // Use the fast case closure allocation code that allocates in new 1089 // Use the fast case closure allocation code that allocates in new
1013 // space for nested functions that don't need literals cloning. 1090 // space for nested functions that don't need literals cloning. If
1014 if (scope()->is_function_scope() && 1091 // we're running with the --always-opt or the --prepare-always-opt
1092 // flag, we need to use the runtime function so that the new function
1093 // we are creating here gets a chance to have its code optimized and
1094 // doesn't just get a copy of the existing unoptimized code.
1095 if (!FLAG_always_opt &&
1096 !FLAG_prepare_always_opt &&
1097 scope()->is_function_scope() &&
1015 info->num_literals() == 0 && 1098 info->num_literals() == 0 &&
1016 !pretenure) { 1099 !pretenure) {
1017 FastNewClosureStub stub; 1100 FastNewClosureStub stub;
1018 __ mov(r0, Operand(info)); 1101 __ mov(r0, Operand(info));
1019 __ push(r0); 1102 __ push(r0);
1020 __ CallStub(&stub); 1103 __ CallStub(&stub);
1021 } else { 1104 } else {
1022 __ mov(r0, Operand(info)); 1105 __ mov(r0, Operand(info));
1023 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex 1106 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex
1024 : Heap::kFalseValueRootIndex); 1107 : Heap::kFalseValueRootIndex);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1341 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1259 context()->Plug(r0); 1342 context()->Plug(r0);
1260 } 1343 }
1261 } 1344 }
1262 1345
1263 1346
1264 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1347 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1265 Comment cmnt(masm_, "[ RegExpLiteral"); 1348 Comment cmnt(masm_, "[ RegExpLiteral");
1266 Label materialized; 1349 Label materialized;
1267 // Registers will be used as follows: 1350 // Registers will be used as follows:
1351 // r5 = materialized value (RegExp literal)
1268 // r4 = JS function, literals array 1352 // r4 = JS function, literals array
1269 // r3 = literal index 1353 // r3 = literal index
1270 // r2 = RegExp pattern 1354 // r2 = RegExp pattern
1271 // r1 = RegExp flags 1355 // r1 = RegExp flags
1272 // r0 = temp + materialized value (RegExp literal) 1356 // r0 = RegExp literal clone
1273 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1357 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1274 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); 1358 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
1275 int literal_offset = 1359 int literal_offset =
1276 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 1360 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
1277 __ ldr(r0, FieldMemOperand(r4, literal_offset)); 1361 __ ldr(r5, FieldMemOperand(r4, literal_offset));
1278 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1362 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1279 __ cmp(r0, ip); 1363 __ cmp(r5, ip);
1280 __ b(ne, &materialized); 1364 __ b(ne, &materialized);
1281 1365
1282 // Create regexp literal using runtime function. 1366 // Create regexp literal using runtime function.
1283 // Result will be in r0. 1367 // Result will be in r0.
1284 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); 1368 __ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
1285 __ mov(r2, Operand(expr->pattern())); 1369 __ mov(r2, Operand(expr->pattern()));
1286 __ mov(r1, Operand(expr->flags())); 1370 __ mov(r1, Operand(expr->flags()));
1287 __ Push(r4, r3, r2, r1); 1371 __ Push(r4, r3, r2, r1);
1288 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 1372 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1373 __ mov(r5, r0);
1289 1374
1290 __ bind(&materialized); 1375 __ bind(&materialized);
1291 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 1376 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1292 __ push(r0); 1377 Label allocated, runtime_allocate;
1378 __ AllocateInNewSpace(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
1379 __ jmp(&allocated);
1380
1381 __ bind(&runtime_allocate);
1382 __ push(r5);
1293 __ mov(r0, Operand(Smi::FromInt(size))); 1383 __ mov(r0, Operand(Smi::FromInt(size)));
1294 __ push(r0); 1384 __ push(r0);
1295 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 1385 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1386 __ pop(r5);
1296 1387
1388 __ bind(&allocated);
1297 // After this, registers are used as follows: 1389 // After this, registers are used as follows:
1298 // r0: Newly allocated regexp. 1390 // r0: Newly allocated regexp.
1299 // r1: Materialized regexp. 1391 // r5: Materialized regexp.
1300 // r2: temp. 1392 // r2: temp.
1301 __ pop(r1); 1393 __ CopyFields(r0, r5, r2.bit(), size / kPointerSize);
1302 __ CopyFields(r0, r1, r2.bit(), size / kPointerSize);
1303 context()->Plug(r0); 1394 context()->Plug(r0);
1304 } 1395 }
1305 1396
1306 1397
1307 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1398 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1308 Comment cmnt(masm_, "[ ObjectLiteral"); 1399 Comment cmnt(masm_, "[ ObjectLiteral");
1309 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1400 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1310 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); 1401 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
1311 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); 1402 __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
1312 __ mov(r1, Operand(expr->constant_properties())); 1403 __ mov(r1, Operand(expr->constant_properties()));
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after
3127 VisitForStackValue(args->at(0)); 3218 VisitForStackValue(args->at(0));
3128 VisitForStackValue(args->at(1)); 3219 VisitForStackValue(args->at(1));
3129 3220
3130 StringCompareStub stub; 3221 StringCompareStub stub;
3131 __ CallStub(&stub); 3222 __ CallStub(&stub);
3132 context()->Plug(r0); 3223 context()->Plug(r0);
3133 } 3224 }
3134 3225
3135 3226
3136 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { 3227 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
3137 // Load the argument on the stack and call the runtime. 3228 // Load the argument on the stack and call the stub.
3229 TranscendentalCacheStub stub(TranscendentalCache::SIN);
3138 ASSERT(args->length() == 1); 3230 ASSERT(args->length() == 1);
3139 VisitForStackValue(args->at(0)); 3231 VisitForStackValue(args->at(0));
3140 __ CallRuntime(Runtime::kMath_sin, 1); 3232 __ CallStub(&stub);
3141 context()->Plug(r0); 3233 context()->Plug(r0);
3142 } 3234 }
3143 3235
3144 3236
3145 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { 3237 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
3146 // Load the argument on the stack and call the runtime. 3238 // Load the argument on the stack and call the stub.
3239 TranscendentalCacheStub stub(TranscendentalCache::COS);
3147 ASSERT(args->length() == 1); 3240 ASSERT(args->length() == 1);
3148 VisitForStackValue(args->at(0)); 3241 VisitForStackValue(args->at(0));
3149 __ CallRuntime(Runtime::kMath_cos, 1); 3242 __ CallStub(&stub);
3243 context()->Plug(r0);
3244 }
3245
3246
3247 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
3248 // Load the argument on the stack and call the stub.
3249 TranscendentalCacheStub stub(TranscendentalCache::LOG);
3250 ASSERT(args->length() == 1);
3251 VisitForStackValue(args->at(0));
3252 __ CallStub(&stub);
3150 context()->Plug(r0); 3253 context()->Plug(r0);
3151 } 3254 }
3152 3255
3153 3256
3154 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { 3257 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
3155 // Load the argument on the stack and call the runtime function. 3258 // Load the argument on the stack and call the runtime function.
3156 ASSERT(args->length() == 1); 3259 ASSERT(args->length() == 1);
3157 VisitForStackValue(args->at(0)); 3260 VisitForStackValue(args->at(0));
3158 __ CallRuntime(Runtime::kMath_sqrt, 1); 3261 __ CallRuntime(Runtime::kMath_sqrt, 1);
3159 context()->Plug(r0); 3262 context()->Plug(r0);
3160 } 3263 }
3161 3264
3162
3163 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
3164 // Load the argument on the stack and call the runtime function.
3165 ASSERT(args->length() == 1);
3166 VisitForStackValue(args->at(0));
3167 __ CallRuntime(Runtime::kMath_log, 1);
3168 context()->Plug(r0);
3169 }
3170
3171 3265
3172 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { 3266 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
3173 ASSERT(args->length() >= 2); 3267 ASSERT(args->length() >= 2);
3174 3268
3175 int arg_count = args->length() - 2; // For receiver and function. 3269 int arg_count = args->length() - 2; // For receiver and function.
3176 VisitForStackValue(args->at(0)); // Receiver. 3270 VisitForStackValue(args->at(0)); // Receiver.
3177 for (int i = 0; i < arg_count; i++) { 3271 for (int i = 0; i < arg_count; i++) {
3178 VisitForStackValue(args->at(i + 1)); 3272 VisitForStackValue(args->at(i + 1));
3179 } 3273 }
3180 VisitForAccumulatorValue(args->at(arg_count + 1)); // Function. 3274 VisitForAccumulatorValue(args->at(arg_count + 1)); // Function.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
3316 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 3410 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
3317 Split(eq, if_true, if_false, fall_through); 3411 Split(eq, if_true, if_false, fall_through);
3318 3412
3319 context()->Plug(if_true, if_false); 3413 context()->Plug(if_true, if_false);
3320 } 3414 }
3321 3415
3322 3416
3323 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { 3417 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) {
3324 ASSERT(args->length() == 1); 3418 ASSERT(args->length() == 1);
3325 VisitForAccumulatorValue(args->at(0)); 3419 VisitForAccumulatorValue(args->at(0));
3420
3421 if (FLAG_debug_code) {
3422 __ AbortIfNotString(r0);
3423 }
3424
3326 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); 3425 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset));
3327 __ IndexFromHash(r0, r0); 3426 __ IndexFromHash(r0, r0);
3427
3328 context()->Plug(r0); 3428 context()->Plug(r0);
3329 } 3429 }
3330 3430
3331 3431
3332 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) { 3432 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
3333 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 3433 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
3334 context()->Plug(r0); 3434 context()->Plug(r0);
3335 return; 3435 return;
3336 } 3436 }
3337 3437
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
3479 __ bind(&no_conversion); 3579 __ bind(&no_conversion);
3480 context()->Plug(result_register()); 3580 context()->Plug(result_register());
3481 break; 3581 break;
3482 } 3582 }
3483 3583
3484 case Token::SUB: { 3584 case Token::SUB: {
3485 Comment cmt(masm_, "[ UnaryOperation (SUB)"); 3585 Comment cmt(masm_, "[ UnaryOperation (SUB)");
3486 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); 3586 bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
3487 UnaryOverwriteMode overwrite = 3587 UnaryOverwriteMode overwrite =
3488 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; 3588 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
3489 GenericUnaryOpStub stub(Token::SUB, 3589 GenericUnaryOpStub stub(Token::SUB, overwrite, NO_UNARY_FLAGS);
3490 overwrite,
3491 NO_UNARY_FLAGS);
3492 // GenericUnaryOpStub expects the argument to be in the 3590 // GenericUnaryOpStub expects the argument to be in the
3493 // accumulator register r0. 3591 // accumulator register r0.
3494 VisitForAccumulatorValue(expr->expression()); 3592 VisitForAccumulatorValue(expr->expression());
3495 __ CallStub(&stub); 3593 __ CallStub(&stub);
3496 context()->Plug(r0); 3594 context()->Plug(r0);
3497 break; 3595 break;
3498 } 3596 }
3499 3597
3500 case Token::BIT_NOT: { 3598 case Token::BIT_NOT: {
3501 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); 3599 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
3991 4089
3992 4090
3993 Register FullCodeGenerator::context_register() { 4091 Register FullCodeGenerator::context_register() {
3994 return cp; 4092 return cp;
3995 } 4093 }
3996 4094
3997 4095
3998 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 4096 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
3999 ASSERT(mode == RelocInfo::CODE_TARGET || 4097 ASSERT(mode == RelocInfo::CODE_TARGET ||
4000 mode == RelocInfo::CODE_TARGET_CONTEXT); 4098 mode == RelocInfo::CODE_TARGET_CONTEXT);
4099 switch (ic->kind()) {
4100 case Code::LOAD_IC:
4101 __ IncrementCounter(&Counters::named_load_full, 1, r1, r2);
4102 break;
4103 case Code::KEYED_LOAD_IC:
4104 __ IncrementCounter(&Counters::keyed_load_full, 1, r1, r2);
4105 break;
4106 case Code::STORE_IC:
4107 __ IncrementCounter(&Counters::named_store_full, 1, r1, r2);
4108 break;
4109 case Code::KEYED_STORE_IC:
4110 __ IncrementCounter(&Counters::keyed_store_full, 1, r1, r2);
4111 default:
4112 break;
4113 }
4114
4001 __ Call(ic, mode); 4115 __ Call(ic, mode);
4002 } 4116 }
4003 4117
4004 4118
4005 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { 4119 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
4120 switch (ic->kind()) {
4121 case Code::LOAD_IC:
4122 __ IncrementCounter(&Counters::named_load_full, 1, r1, r2);
4123 break;
4124 case Code::KEYED_LOAD_IC:
4125 __ IncrementCounter(&Counters::keyed_load_full, 1, r1, r2);
4126 break;
4127 case Code::STORE_IC:
4128 __ IncrementCounter(&Counters::named_store_full, 1, r1, r2);
4129 break;
4130 case Code::KEYED_STORE_IC:
4131 __ IncrementCounter(&Counters::keyed_store_full, 1, r1, r2);
4132 default:
4133 break;
4134 }
4135
4006 __ Call(ic, RelocInfo::CODE_TARGET); 4136 __ Call(ic, RelocInfo::CODE_TARGET);
4007 if (patch_site != NULL && patch_site->is_bound()) { 4137 if (patch_site != NULL && patch_site->is_bound()) {
4008 patch_site->EmitPatchInfo(); 4138 patch_site->EmitPatchInfo();
4009 } else { 4139 } else {
4010 __ nop(); // Signals no inlined code. 4140 __ nop(); // Signals no inlined code.
4011 } 4141 }
4012 } 4142 }
4013 4143
4014 4144
4015 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4145 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4049 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4179 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4050 __ add(pc, r1, Operand(masm_->CodeObject())); 4180 __ add(pc, r1, Operand(masm_->CodeObject()));
4051 } 4181 }
4052 4182
4053 4183
4054 #undef __ 4184 #undef __
4055 4185
4056 } } // namespace v8::internal 4186 } } // namespace v8::internal
4057 4187
4058 #endif // V8_TARGET_ARCH_ARM 4188 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/lithium-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698