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

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

Issue 10945: Experimental: periodic merge to the experimental branch from... (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/api.cc ('k') | src/codegen-ia32.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 3110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 3121
3122 3122
3123 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 3123 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
3124 Comment cmnt(masm_, "[ CompareOperation"); 3124 Comment cmnt(masm_, "[ CompareOperation");
3125 3125
3126 // Get the expressions from the node. 3126 // Get the expressions from the node.
3127 Expression* left = node->left(); 3127 Expression* left = node->left();
3128 Expression* right = node->right(); 3128 Expression* right = node->right();
3129 Token::Value op = node->op(); 3129 Token::Value op = node->op();
3130 3130
3131 // NOTE: To make null checks efficient, we check if either left or 3131 // To make null checks efficient, we check if either left or right is the
3132 // right is the literal 'null'. If so, we optimize the code by 3132 // literal 'null'. If so, we optimize the code by inlining a null check
3133 // inlining a null check instead of calling the (very) general 3133 // instead of calling the (very) general runtime routine for checking
3134 // runtime routine for checking equality. 3134 // equality.
3135
3136 if (op == Token::EQ || op == Token::EQ_STRICT) { 3135 if (op == Token::EQ || op == Token::EQ_STRICT) {
3137 bool left_is_null = 3136 bool left_is_null =
3138 left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); 3137 left->AsLiteral() != NULL && left->AsLiteral()->IsNull();
3139 bool right_is_null = 3138 bool right_is_null =
3140 right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); 3139 right->AsLiteral() != NULL && right->AsLiteral()->IsNull();
3141 // The 'null' value is only equal to 'null' or 'undefined'. 3140 // The 'null' value can only be equal to 'null' or 'undefined'.
3142 if (left_is_null || right_is_null) { 3141 if (left_is_null || right_is_null) {
3143 Load(left_is_null ? right : left); 3142 Load(left_is_null ? right : left);
3144 JumpTarget exit(this);
3145 JumpTarget undetectable(this);
3146 frame_->Pop(r0); 3143 frame_->Pop(r0);
3147 __ cmp(r0, Operand(Factory::null_value())); 3144 __ cmp(r0, Operand(Factory::null_value()));
3148 3145
3149 // The 'null' value is only equal to 'undefined' if using 3146 // The 'null' value is only equal to 'undefined' if using non-strict
3150 // non-strict comparisons. 3147 // comparisons.
3151 if (op != Token::EQ_STRICT) { 3148 if (op != Token::EQ_STRICT) {
3152 exit.Branch(eq); 3149 true_target()->Branch();
3150
3153 __ cmp(r0, Operand(Factory::undefined_value())); 3151 __ cmp(r0, Operand(Factory::undefined_value()));
3152 true_target()->Branch(eq);
3154 3153
3155 // NOTE: it can be undetectable object.
3156 exit.Branch(eq);
3157 __ tst(r0, Operand(kSmiTagMask)); 3154 __ tst(r0, Operand(kSmiTagMask));
3155 false_target()->Branch(eq);
3158 3156
3159 undetectable.Branch(ne); 3157 // It can be an undetectable object.
3160 false_target()->Jump(); 3158 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
3161 3159 __ ldrb(r0, FieldMemOperand(r0, Map::kBitFieldOffset));
3162 undetectable.Bind(); 3160 __ and_(r0, r0, Operand(1 << Map::kIsUndetectable));
3163 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 3161 __ cmp(r0, Operand(1 << Map::kIsUndetectable));
3164 __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset));
3165 __ and_(r2, r2, Operand(1 << Map::kIsUndetectable));
3166 __ cmp(r2, Operand(1 << Map::kIsUndetectable));
3167 } 3162 }
3168 3163
3169 exit.Bind();
3170
3171 cc_reg_ = eq; 3164 cc_reg_ = eq;
3172 return; 3165 return;
3173 } 3166 }
3174 } 3167 }
3175 3168
3176 3169 // To make typeof testing for natives implemented in JavaScript really
3177 // NOTE: To make typeof testing for natives implemented in 3170 // efficient, we generate special code for expressions of the form:
3178 // JavaScript really efficient, we generate special code for 3171 // 'typeof <expression> == <string>'.
3179 // expressions of the form: 'typeof <expression> == <string>'.
3180
3181 UnaryOperation* operation = left->AsUnaryOperation(); 3172 UnaryOperation* operation = left->AsUnaryOperation();
3182 if ((op == Token::EQ || op == Token::EQ_STRICT) && 3173 if ((op == Token::EQ || op == Token::EQ_STRICT) &&
3183 (operation != NULL && operation->op() == Token::TYPEOF) && 3174 (operation != NULL && operation->op() == Token::TYPEOF) &&
3184 (right->AsLiteral() != NULL && 3175 (right->AsLiteral() != NULL &&
3185 right->AsLiteral()->handle()->IsString())) { 3176 right->AsLiteral()->handle()->IsString())) {
3186 Handle<String> check(String::cast(*right->AsLiteral()->handle())); 3177 Handle<String> check(String::cast(*right->AsLiteral()->handle()));
3187 3178
3188 // Load the operand, move it to register r1. 3179 // Load the operand, move it to register r1.
3189 LoadTypeofExpression(operation->expression()); 3180 LoadTypeofExpression(operation->expression());
3190 frame_->Pop(r1); 3181 frame_->Pop(r1);
3191 3182
3192 if (check->Equals(Heap::number_symbol())) { 3183 if (check->Equals(Heap::number_symbol())) {
3193 __ tst(r1, Operand(kSmiTagMask)); 3184 __ tst(r1, Operand(kSmiTagMask));
3194 true_target()->Branch(eq); 3185 true_target()->Branch(eq);
3195 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); 3186 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
3196 __ cmp(r1, Operand(Factory::heap_number_map())); 3187 __ cmp(r1, Operand(Factory::heap_number_map()));
3197 cc_reg_ = eq; 3188 cc_reg_ = eq;
3198 3189
3199 } else if (check->Equals(Heap::string_symbol())) { 3190 } else if (check->Equals(Heap::string_symbol())) {
3200 __ tst(r1, Operand(kSmiTagMask)); 3191 __ tst(r1, Operand(kSmiTagMask));
3201 false_target()->Branch(eq); 3192 false_target()->Branch(eq);
3202 3193
3203 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); 3194 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
3204 3195
3205 // NOTE: it might be an undetectable string object 3196 // It can be an undetectable string object.
3206 __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset)); 3197 __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset));
3207 __ and_(r2, r2, Operand(1 << Map::kIsUndetectable)); 3198 __ and_(r2, r2, Operand(1 << Map::kIsUndetectable));
3208 __ cmp(r2, Operand(1 << Map::kIsUndetectable)); 3199 __ cmp(r2, Operand(1 << Map::kIsUndetectable));
3209 false_target()->Branch(eq); 3200 false_target()->Branch(eq);
3210 3201
3211 __ ldrb(r2, FieldMemOperand(r1, Map::kInstanceTypeOffset)); 3202 __ ldrb(r2, FieldMemOperand(r1, Map::kInstanceTypeOffset));
3212 __ cmp(r2, Operand(FIRST_NONSTRING_TYPE)); 3203 __ cmp(r2, Operand(FIRST_NONSTRING_TYPE));
3213 cc_reg_ = lt; 3204 cc_reg_ = lt;
3214 3205
3215 } else if (check->Equals(Heap::boolean_symbol())) { 3206 } else if (check->Equals(Heap::boolean_symbol())) {
3216 __ cmp(r1, Operand(Factory::true_value())); 3207 __ cmp(r1, Operand(Factory::true_value()));
3217 true_target()->Branch(eq); 3208 true_target()->Branch(eq);
3218 __ cmp(r1, Operand(Factory::false_value())); 3209 __ cmp(r1, Operand(Factory::false_value()));
3219 cc_reg_ = eq; 3210 cc_reg_ = eq;
3220 3211
3221 } else if (check->Equals(Heap::undefined_symbol())) { 3212 } else if (check->Equals(Heap::undefined_symbol())) {
3222 __ cmp(r1, Operand(Factory::undefined_value())); 3213 __ cmp(r1, Operand(Factory::undefined_value()));
3223 true_target()->Branch(eq); 3214 true_target()->Branch(eq);
3224 3215
3225 __ tst(r1, Operand(kSmiTagMask)); 3216 __ tst(r1, Operand(kSmiTagMask));
3226 false_target()->Branch(eq); 3217 false_target()->Branch(eq);
3227 3218
3228 // NOTE: it can be undetectable object. 3219 // It can be an undetectable object.
3229 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); 3220 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
3230 __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset)); 3221 __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset));
3231 __ and_(r2, r2, Operand(1 << Map::kIsUndetectable)); 3222 __ and_(r2, r2, Operand(1 << Map::kIsUndetectable));
3232 __ cmp(r2, Operand(1 << Map::kIsUndetectable)); 3223 __ cmp(r2, Operand(1 << Map::kIsUndetectable));
3233 3224
3234 cc_reg_ = eq; 3225 cc_reg_ = eq;
3235 3226
3236 } else if (check->Equals(Heap::function_symbol())) { 3227 } else if (check->Equals(Heap::function_symbol())) {
3237 __ tst(r1, Operand(kSmiTagMask)); 3228 __ tst(r1, Operand(kSmiTagMask));
3238 false_target()->Branch(eq); 3229 false_target()->Branch(eq);
3239 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); 3230 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
3240 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); 3231 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
3241 __ cmp(r1, Operand(JS_FUNCTION_TYPE)); 3232 __ cmp(r1, Operand(JS_FUNCTION_TYPE));
3242 cc_reg_ = eq; 3233 cc_reg_ = eq;
3243 3234
3244 } else if (check->Equals(Heap::object_symbol())) { 3235 } else if (check->Equals(Heap::object_symbol())) {
3245 __ tst(r1, Operand(kSmiTagMask)); 3236 __ tst(r1, Operand(kSmiTagMask));
3246 false_target()->Branch(eq); 3237 false_target()->Branch(eq);
3247 3238
3248 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 3239 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
3249 __ cmp(r1, Operand(Factory::null_value())); 3240 __ cmp(r1, Operand(Factory::null_value()));
3250 true_target()->Branch(eq); 3241 true_target()->Branch(eq);
3251 3242
3252 // NOTE: it might be an undetectable object. 3243 // It can be an undetectable object.
3253 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); 3244 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset));
3254 __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); 3245 __ and_(r1, r1, Operand(1 << Map::kIsUndetectable));
3255 __ cmp(r1, Operand(1 << Map::kIsUndetectable)); 3246 __ cmp(r1, Operand(1 << Map::kIsUndetectable));
3256 false_target()->Branch(eq); 3247 false_target()->Branch(eq);
3257 3248
3258 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 3249 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
3259 __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE)); 3250 __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE));
3260 false_target()->Branch(lt); 3251 false_target()->Branch(lt);
3261 __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); 3252 __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE));
3262 cc_reg_ = le; 3253 cc_reg_ = le;
3263 3254
3264 } else { 3255 } else {
3265 // Uncommon case: Typeof testing against a string literal that 3256 // Uncommon case: typeof testing against a string literal that is
3266 // is never returned from the typeof operator. 3257 // never returned from the typeof operator.
3267 false_target()->Jump(); 3258 false_target()->Jump();
3268 } 3259 }
3269 return; 3260 return;
3270 } 3261 }
3271 3262
3272 Load(left); 3263 Load(left);
3273 Load(right); 3264 Load(right);
3274 switch (op) { 3265 switch (op) {
3275 case Token::EQ: 3266 case Token::EQ:
3276 Comparison(eq, false); 3267 Comparison(eq, false);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
3384 } 3375 }
3385 frame->Push(r0); 3376 frame->Push(r0);
3386 break; 3377 break;
3387 } 3378 }
3388 3379
3389 case KEYED: { 3380 case KEYED: {
3390 // TODO(1241834): Make sure that this it is safe to ignore the 3381 // TODO(1241834): Make sure that this it is safe to ignore the
3391 // distinction between expressions in a typeof and not in a typeof. 3382 // distinction between expressions in a typeof and not in a typeof.
3392 Comment cmnt(masm, "[ Load from keyed Property"); 3383 Comment cmnt(masm, "[ Load from keyed Property");
3393 ASSERT(property != NULL); 3384 ASSERT(property != NULL);
3394 // TODO(1224671): Implement inline caching for keyed loads as on ia32. 3385 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
3395 GetPropertyStub stub; 3386
3396 frame->CallStub(&stub, 0); 3387 Variable* var = expression_->AsVariableProxy()->AsVariable();
3388 if (var != NULL) {
3389 ASSERT(var->is_global());
3390 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0);
3391 } else {
3392 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
3393 }
3397 frame->Push(r0); 3394 frame->Push(r0);
3398 break; 3395 break;
3399 } 3396 }
3400 3397
3401 default: 3398 default:
3402 UNREACHABLE(); 3399 UNREACHABLE();
3403 } 3400 }
3404 } 3401 }
3405 3402
3406 3403
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3493 if (init_state == CONST_INIT || slot->type() == Slot::CONTEXT) { 3490 if (init_state == CONST_INIT || slot->type() == Slot::CONTEXT) {
3494 exit.Bind(); 3491 exit.Bind();
3495 } 3492 }
3496 } 3493 }
3497 break; 3494 break;
3498 } 3495 }
3499 3496
3500 case NAMED: { 3497 case NAMED: {
3501 Comment cmnt(masm, "[ Store to named Property"); 3498 Comment cmnt(masm, "[ Store to named Property");
3502 // Call the appropriate IC code. 3499 // Call the appropriate IC code.
3500 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
3503 frame->Pop(r0); // value 3501 frame->Pop(r0); // value
3504 // Setup the name register. 3502 // Setup the name register.
3505 Handle<String> name(GetName()); 3503 Handle<String> name(GetName());
3506 __ mov(r2, Operand(name)); 3504 __ mov(r2, Operand(name));
3507 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
3508 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 3505 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
3509 frame->Push(r0); 3506 frame->Push(r0);
3510 break; 3507 break;
3511 } 3508 }
3512 3509
3513 case KEYED: { 3510 case KEYED: {
3514 Comment cmnt(masm, "[ Store to keyed Property"); 3511 Comment cmnt(masm, "[ Store to keyed Property");
3515 Property* property = expression_->AsProperty(); 3512 Property* property = expression_->AsProperty();
3516 ASSERT(property != NULL); 3513 ASSERT(property != NULL);
3517 __ RecordPosition(property->position()); 3514 __ RecordPosition(property->position());
3515
3516 // Call IC code.
3517 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
3518 // TODO(1222589): Make the IC grab the values from the stack.
3518 frame->Pop(r0); // value 3519 frame->Pop(r0); // value
3519 SetPropertyStub stub; 3520 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
3520 frame->CallStub(&stub, 0);
3521 frame->Push(r0); 3521 frame->Push(r0);
3522 break; 3522 break;
3523 } 3523 }
3524 3524
3525 default: 3525 default:
3526 UNREACHABLE(); 3526 UNREACHABLE();
3527 } 3527 }
3528 } 3528 }
3529 3529
3530 3530
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
4430 __ mov(r2, Operand(0)); 4430 __ mov(r2, Operand(0));
4431 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 4431 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
4432 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 4432 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
4433 RelocInfo::CODE_TARGET); 4433 RelocInfo::CODE_TARGET);
4434 } 4434 }
4435 4435
4436 4436
4437 #undef __ 4437 #undef __
4438 4438
4439 } } // namespace v8::internal 4439 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698