OLD | NEW |
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 Loading... |
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 // Emit the inlined tests assumed by the stub. |
578 // translate it into control flow to the pair of labels. | 578 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
579 __ push(result_register()); | 579 __ cmp(result_register(), ip); |
580 __ CallRuntime(Runtime::kToBool, 1); | 580 __ b(eq, if_false); |
581 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 581 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
582 __ cmp(r0, ip); | 582 __ cmp(result_register(), ip); |
583 Split(eq, if_true, if_false, fall_through); | 583 __ b(eq, if_true); |
| 584 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 585 __ cmp(result_register(), ip); |
| 586 __ b(eq, if_false); |
| 587 STATIC_ASSERT(kSmiTag == 0); |
| 588 __ tst(result_register(), result_register()); |
| 589 __ b(eq, if_false); |
| 590 __ JumpIfSmi(result_register(), if_true); |
| 591 |
| 592 // Call the ToBoolean stub for all other cases. |
| 593 ToBooleanStub stub(result_register()); |
| 594 __ CallStub(&stub); |
| 595 __ tst(result_register(), result_register()); |
| 596 |
| 597 // The stub returns nonzero for true. |
| 598 Split(ne, if_true, if_false, fall_through); |
584 } | 599 } |
585 | 600 |
586 | 601 |
587 void FullCodeGenerator::Split(Condition cond, | 602 void FullCodeGenerator::Split(Condition cond, |
588 Label* if_true, | 603 Label* if_true, |
589 Label* if_false, | 604 Label* if_false, |
590 Label* fall_through) { | 605 Label* fall_through) { |
591 if (if_false == fall_through) { | 606 if (if_false == fall_through) { |
592 __ b(cond, if_true); | 607 __ b(cond, if_true); |
593 } else if (if_true == fall_through) { | 608 } else if (if_true == fall_through) { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 __ Push(cp, r1, r0); | 804 __ Push(cp, r1, r0); |
790 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 805 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
791 // Return value is ignored. | 806 // Return value is ignored. |
792 } | 807 } |
793 | 808 |
794 | 809 |
795 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 810 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
796 Comment cmnt(masm_, "[ SwitchStatement"); | 811 Comment cmnt(masm_, "[ SwitchStatement"); |
797 Breakable nested_statement(this, stmt); | 812 Breakable nested_statement(this, stmt); |
798 SetStatementPosition(stmt); | 813 SetStatementPosition(stmt); |
| 814 |
799 // Keep the switch value on the stack until a case matches. | 815 // Keep the switch value on the stack until a case matches. |
800 VisitForStackValue(stmt->tag()); | 816 VisitForStackValue(stmt->tag()); |
801 | |
802 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 817 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
803 | 818 |
804 ZoneList<CaseClause*>* clauses = stmt->cases(); | 819 ZoneList<CaseClause*>* clauses = stmt->cases(); |
805 CaseClause* default_clause = NULL; // Can occur anywhere in the list. | 820 CaseClause* default_clause = NULL; // Can occur anywhere in the list. |
806 | 821 |
807 Label next_test; // Recycled for each test. | 822 Label next_test; // Recycled for each test. |
808 // Compile all the tests with branches to their bodies. | 823 // Compile all the tests with branches to their bodies. |
809 for (int i = 0; i < clauses->length(); i++) { | 824 for (int i = 0; i < clauses->length(); i++) { |
810 CaseClause* clause = clauses->at(i); | 825 CaseClause* clause = clauses->at(i); |
811 clause->body_target()->entry_label()->Unuse(); | 826 clause->body_target()->entry_label()->Unuse(); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 | 1070 |
1056 // Exit and decrement the loop depth. | 1071 // Exit and decrement the loop depth. |
1057 __ bind(&exit); | 1072 __ bind(&exit); |
1058 decrement_loop_depth(); | 1073 decrement_loop_depth(); |
1059 } | 1074 } |
1060 | 1075 |
1061 | 1076 |
1062 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1077 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
1063 bool pretenure) { | 1078 bool pretenure) { |
1064 // Use the fast case closure allocation code that allocates in new | 1079 // Use the fast case closure allocation code that allocates in new |
1065 // space for nested functions that don't need literals cloning. | 1080 // space for nested functions that don't need literals cloning. If |
1066 if (scope()->is_function_scope() && | 1081 // we're running with the --always-opt or the --prepare-always-opt |
| 1082 // flag, we need to use the runtime function so that the new function |
| 1083 // we are creating here gets a chance to have its code optimized and |
| 1084 // doesn't just get a copy of the existing unoptimized code. |
| 1085 if (!FLAG_always_opt && |
| 1086 !FLAG_prepare_always_opt && |
| 1087 scope()->is_function_scope() && |
1067 info->num_literals() == 0 && | 1088 info->num_literals() == 0 && |
1068 !pretenure) { | 1089 !pretenure) { |
1069 FastNewClosureStub stub; | 1090 FastNewClosureStub stub; |
1070 __ mov(r0, Operand(info)); | 1091 __ mov(r0, Operand(info)); |
1071 __ push(r0); | 1092 __ push(r0); |
1072 __ CallStub(&stub); | 1093 __ CallStub(&stub); |
1073 } else { | 1094 } else { |
1074 __ mov(r0, Operand(info)); | 1095 __ mov(r0, Operand(info)); |
1075 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex | 1096 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex |
1076 : Heap::kFalseValueRootIndex); | 1097 : Heap::kFalseValueRootIndex); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1331 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1311 context()->Plug(r0); | 1332 context()->Plug(r0); |
1312 } | 1333 } |
1313 } | 1334 } |
1314 | 1335 |
1315 | 1336 |
1316 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1337 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1317 Comment cmnt(masm_, "[ RegExpLiteral"); | 1338 Comment cmnt(masm_, "[ RegExpLiteral"); |
1318 Label materialized; | 1339 Label materialized; |
1319 // Registers will be used as follows: | 1340 // Registers will be used as follows: |
| 1341 // r5 = materialized value (RegExp literal) |
1320 // r4 = JS function, literals array | 1342 // r4 = JS function, literals array |
1321 // r3 = literal index | 1343 // r3 = literal index |
1322 // r2 = RegExp pattern | 1344 // r2 = RegExp pattern |
1323 // r1 = RegExp flags | 1345 // r1 = RegExp flags |
1324 // r0 = temp + materialized value (RegExp literal) | 1346 // r0 = RegExp literal clone |
1325 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1347 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1326 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); | 1348 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); |
1327 int literal_offset = | 1349 int literal_offset = |
1328 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; | 1350 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; |
1329 __ ldr(r0, FieldMemOperand(r4, literal_offset)); | 1351 __ ldr(r5, FieldMemOperand(r4, literal_offset)); |
1330 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1352 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
1331 __ cmp(r0, ip); | 1353 __ cmp(r5, ip); |
1332 __ b(ne, &materialized); | 1354 __ b(ne, &materialized); |
1333 | 1355 |
1334 // Create regexp literal using runtime function. | 1356 // Create regexp literal using runtime function. |
1335 // Result will be in r0. | 1357 // Result will be in r0. |
1336 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); | 1358 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); |
1337 __ mov(r2, Operand(expr->pattern())); | 1359 __ mov(r2, Operand(expr->pattern())); |
1338 __ mov(r1, Operand(expr->flags())); | 1360 __ mov(r1, Operand(expr->flags())); |
1339 __ Push(r4, r3, r2, r1); | 1361 __ Push(r4, r3, r2, r1); |
1340 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 1362 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
| 1363 __ mov(r5, r0); |
1341 | 1364 |
1342 __ bind(&materialized); | 1365 __ bind(&materialized); |
1343 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 1366 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
1344 __ push(r0); | 1367 Label allocated, runtime_allocate; |
| 1368 __ AllocateInNewSpace(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); |
| 1369 __ jmp(&allocated); |
| 1370 |
| 1371 __ bind(&runtime_allocate); |
| 1372 __ push(r5); |
1345 __ mov(r0, Operand(Smi::FromInt(size))); | 1373 __ mov(r0, Operand(Smi::FromInt(size))); |
1346 __ push(r0); | 1374 __ push(r0); |
1347 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 1375 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| 1376 __ pop(r5); |
1348 | 1377 |
| 1378 __ bind(&allocated); |
1349 // After this, registers are used as follows: | 1379 // After this, registers are used as follows: |
1350 // r0: Newly allocated regexp. | 1380 // r0: Newly allocated regexp. |
1351 // r1: Materialized regexp. | 1381 // r5: Materialized regexp. |
1352 // r2: temp. | 1382 // r2: temp. |
1353 __ pop(r1); | 1383 __ CopyFields(r0, r5, r2.bit(), size / kPointerSize); |
1354 __ CopyFields(r0, r1, r2.bit(), size / kPointerSize); | |
1355 context()->Plug(r0); | 1384 context()->Plug(r0); |
1356 } | 1385 } |
1357 | 1386 |
1358 | 1387 |
1359 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1388 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
1360 Comment cmnt(masm_, "[ ObjectLiteral"); | 1389 Comment cmnt(masm_, "[ ObjectLiteral"); |
1361 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1390 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1362 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 1391 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
1363 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 1392 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
1364 __ mov(r1, Operand(expr->constant_properties())); | 1393 __ mov(r1, Operand(expr->constant_properties())); |
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3179 VisitForStackValue(args->at(0)); | 3208 VisitForStackValue(args->at(0)); |
3180 VisitForStackValue(args->at(1)); | 3209 VisitForStackValue(args->at(1)); |
3181 | 3210 |
3182 StringCompareStub stub; | 3211 StringCompareStub stub; |
3183 __ CallStub(&stub); | 3212 __ CallStub(&stub); |
3184 context()->Plug(r0); | 3213 context()->Plug(r0); |
3185 } | 3214 } |
3186 | 3215 |
3187 | 3216 |
3188 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { | 3217 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { |
3189 // Load the argument on the stack and call the runtime. | 3218 // Load the argument on the stack and call the stub. |
| 3219 TranscendentalCacheStub stub(TranscendentalCache::SIN); |
3190 ASSERT(args->length() == 1); | 3220 ASSERT(args->length() == 1); |
3191 VisitForStackValue(args->at(0)); | 3221 VisitForStackValue(args->at(0)); |
3192 __ CallRuntime(Runtime::kMath_sin, 1); | 3222 __ CallStub(&stub); |
3193 context()->Plug(r0); | 3223 context()->Plug(r0); |
3194 } | 3224 } |
3195 | 3225 |
3196 | 3226 |
3197 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { | 3227 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { |
3198 // 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::COS); |
3199 ASSERT(args->length() == 1); | 3230 ASSERT(args->length() == 1); |
3200 VisitForStackValue(args->at(0)); | 3231 VisitForStackValue(args->at(0)); |
3201 __ CallRuntime(Runtime::kMath_cos, 1); | 3232 __ CallStub(&stub); |
| 3233 context()->Plug(r0); |
| 3234 } |
| 3235 |
| 3236 |
| 3237 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { |
| 3238 // Load the argument on the stack and call the stub. |
| 3239 TranscendentalCacheStub stub(TranscendentalCache::LOG); |
| 3240 ASSERT(args->length() == 1); |
| 3241 VisitForStackValue(args->at(0)); |
| 3242 __ CallStub(&stub); |
3202 context()->Plug(r0); | 3243 context()->Plug(r0); |
3203 } | 3244 } |
3204 | 3245 |
3205 | 3246 |
3206 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { | 3247 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { |
3207 // Load the argument on the stack and call the runtime function. | 3248 // Load the argument on the stack and call the runtime function. |
3208 ASSERT(args->length() == 1); | 3249 ASSERT(args->length() == 1); |
3209 VisitForStackValue(args->at(0)); | 3250 VisitForStackValue(args->at(0)); |
3210 __ CallRuntime(Runtime::kMath_sqrt, 1); | 3251 __ CallRuntime(Runtime::kMath_sqrt, 1); |
3211 context()->Plug(r0); | 3252 context()->Plug(r0); |
3212 } | 3253 } |
3213 | 3254 |
3214 | |
3215 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { | |
3216 // Load the argument on the stack and call the runtime function. | |
3217 ASSERT(args->length() == 1); | |
3218 VisitForStackValue(args->at(0)); | |
3219 __ CallRuntime(Runtime::kMath_log, 1); | |
3220 context()->Plug(r0); | |
3221 } | |
3222 | |
3223 | 3255 |
3224 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { | 3256 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { |
3225 ASSERT(args->length() >= 2); | 3257 ASSERT(args->length() >= 2); |
3226 | 3258 |
3227 int arg_count = args->length() - 2; // For receiver and function. | 3259 int arg_count = args->length() - 2; // For receiver and function. |
3228 VisitForStackValue(args->at(0)); // Receiver. | 3260 VisitForStackValue(args->at(0)); // Receiver. |
3229 for (int i = 0; i < arg_count; i++) { | 3261 for (int i = 0; i < arg_count; i++) { |
3230 VisitForStackValue(args->at(i + 1)); | 3262 VisitForStackValue(args->at(i + 1)); |
3231 } | 3263 } |
3232 VisitForAccumulatorValue(args->at(arg_count + 1)); // Function. | 3264 VisitForAccumulatorValue(args->at(arg_count + 1)); // Function. |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3368 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 3400 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
3369 Split(eq, if_true, if_false, fall_through); | 3401 Split(eq, if_true, if_false, fall_through); |
3370 | 3402 |
3371 context()->Plug(if_true, if_false); | 3403 context()->Plug(if_true, if_false); |
3372 } | 3404 } |
3373 | 3405 |
3374 | 3406 |
3375 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { | 3407 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { |
3376 ASSERT(args->length() == 1); | 3408 ASSERT(args->length() == 1); |
3377 VisitForAccumulatorValue(args->at(0)); | 3409 VisitForAccumulatorValue(args->at(0)); |
| 3410 |
| 3411 if (FLAG_debug_code) { |
| 3412 __ AbortIfNotString(r0); |
| 3413 } |
| 3414 |
3378 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); | 3415 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); |
3379 __ IndexFromHash(r0, r0); | 3416 __ IndexFromHash(r0, r0); |
| 3417 |
3380 context()->Plug(r0); | 3418 context()->Plug(r0); |
3381 } | 3419 } |
3382 | 3420 |
3383 | 3421 |
3384 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) { | 3422 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) { |
3385 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3423 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
3386 context()->Plug(r0); | 3424 context()->Plug(r0); |
3387 return; | 3425 return; |
3388 } | 3426 } |
3389 | 3427 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3531 __ bind(&no_conversion); | 3569 __ bind(&no_conversion); |
3532 context()->Plug(result_register()); | 3570 context()->Plug(result_register()); |
3533 break; | 3571 break; |
3534 } | 3572 } |
3535 | 3573 |
3536 case Token::SUB: { | 3574 case Token::SUB: { |
3537 Comment cmt(masm_, "[ UnaryOperation (SUB)"); | 3575 Comment cmt(masm_, "[ UnaryOperation (SUB)"); |
3538 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3576 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
3539 UnaryOverwriteMode overwrite = | 3577 UnaryOverwriteMode overwrite = |
3540 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3578 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
3541 GenericUnaryOpStub stub(Token::SUB, | 3579 GenericUnaryOpStub stub(Token::SUB, overwrite, NO_UNARY_FLAGS); |
3542 overwrite, | |
3543 NO_UNARY_FLAGS); | |
3544 // GenericUnaryOpStub expects the argument to be in the | 3580 // GenericUnaryOpStub expects the argument to be in the |
3545 // accumulator register r0. | 3581 // accumulator register r0. |
3546 VisitForAccumulatorValue(expr->expression()); | 3582 VisitForAccumulatorValue(expr->expression()); |
3547 __ CallStub(&stub); | 3583 __ CallStub(&stub); |
3548 context()->Plug(r0); | 3584 context()->Plug(r0); |
3549 break; | 3585 break; |
3550 } | 3586 } |
3551 | 3587 |
3552 case Token::BIT_NOT: { | 3588 case Token::BIT_NOT: { |
3553 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); | 3589 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4043 | 4079 |
4044 | 4080 |
4045 Register FullCodeGenerator::context_register() { | 4081 Register FullCodeGenerator::context_register() { |
4046 return cp; | 4082 return cp; |
4047 } | 4083 } |
4048 | 4084 |
4049 | 4085 |
4050 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { | 4086 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { |
4051 ASSERT(mode == RelocInfo::CODE_TARGET || | 4087 ASSERT(mode == RelocInfo::CODE_TARGET || |
4052 mode == RelocInfo::CODE_TARGET_CONTEXT); | 4088 mode == RelocInfo::CODE_TARGET_CONTEXT); |
| 4089 switch (ic->kind()) { |
| 4090 case Code::LOAD_IC: |
| 4091 __ IncrementCounter(&Counters::named_load_full, 1, r1, r2); |
| 4092 break; |
| 4093 case Code::KEYED_LOAD_IC: |
| 4094 __ IncrementCounter(&Counters::keyed_load_full, 1, r1, r2); |
| 4095 break; |
| 4096 case Code::STORE_IC: |
| 4097 __ IncrementCounter(&Counters::named_store_full, 1, r1, r2); |
| 4098 break; |
| 4099 case Code::KEYED_STORE_IC: |
| 4100 __ IncrementCounter(&Counters::keyed_store_full, 1, r1, r2); |
| 4101 default: |
| 4102 break; |
| 4103 } |
| 4104 |
4053 __ Call(ic, mode); | 4105 __ Call(ic, mode); |
4054 } | 4106 } |
4055 | 4107 |
4056 | 4108 |
4057 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { | 4109 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { |
| 4110 switch (ic->kind()) { |
| 4111 case Code::LOAD_IC: |
| 4112 __ IncrementCounter(&Counters::named_load_full, 1, r1, r2); |
| 4113 break; |
| 4114 case Code::KEYED_LOAD_IC: |
| 4115 __ IncrementCounter(&Counters::keyed_load_full, 1, r1, r2); |
| 4116 break; |
| 4117 case Code::STORE_IC: |
| 4118 __ IncrementCounter(&Counters::named_store_full, 1, r1, r2); |
| 4119 break; |
| 4120 case Code::KEYED_STORE_IC: |
| 4121 __ IncrementCounter(&Counters::keyed_store_full, 1, r1, r2); |
| 4122 default: |
| 4123 break; |
| 4124 } |
| 4125 |
4058 __ Call(ic, RelocInfo::CODE_TARGET); | 4126 __ Call(ic, RelocInfo::CODE_TARGET); |
4059 if (patch_site != NULL && patch_site->is_bound()) { | 4127 if (patch_site != NULL && patch_site->is_bound()) { |
4060 patch_site->EmitPatchInfo(); | 4128 patch_site->EmitPatchInfo(); |
4061 } else { | 4129 } else { |
4062 __ nop(); // Signals no inlined code. | 4130 __ nop(); // Signals no inlined code. |
4063 } | 4131 } |
4064 } | 4132 } |
4065 | 4133 |
4066 | 4134 |
4067 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4135 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4101 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4169 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
4102 __ add(pc, r1, Operand(masm_->CodeObject())); | 4170 __ add(pc, r1, Operand(masm_->CodeObject())); |
4103 } | 4171 } |
4104 | 4172 |
4105 | 4173 |
4106 #undef __ | 4174 #undef __ |
4107 | 4175 |
4108 } } // namespace v8::internal | 4176 } } // namespace v8::internal |
4109 | 4177 |
4110 #endif // V8_TARGET_ARCH_ARM | 4178 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |