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

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

Issue 155723005: A64: Synchronize with r19001. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/a64/code-stubs-a64.cc ('k') | src/a64/ic-a64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 2297 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 ContextualMode mode, 2308 ContextualMode mode,
2309 TypeFeedbackId ast_id) { 2309 TypeFeedbackId ast_id) {
2310 ic_total_count_++; 2310 ic_total_count_++;
2311 // All calls must have a predictable size in full-codegen code to ensure that 2311 // All calls must have a predictable size in full-codegen code to ensure that
2312 // the debugger can patch them correctly. 2312 // the debugger can patch them correctly.
2313 ASSERT((mode != CONTEXTUAL) || ast_id.IsNone()); 2313 ASSERT((mode != CONTEXTUAL) || ast_id.IsNone());
2314 __ Call(code, RelocInfo::CODE_TARGET, ast_id); 2314 __ Call(code, RelocInfo::CODE_TARGET, ast_id);
2315 } 2315 }
2316 2316
2317 2317
2318 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2318 // Code common for calls using the IC.
2319 Handle<Object> name, 2319 void FullCodeGenerator::EmitCallWithIC(Call* expr) {
2320 ContextualMode mode) {
2321 ASM_LOCATION("EmitCallWithIC"); 2320 ASM_LOCATION("EmitCallWithIC");
2322 // Code common for calls using the IC. 2321
2322 Expression* callee = expr->expression();
2323 ZoneList<Expression*>* args = expr->arguments(); 2323 ZoneList<Expression*>* args = expr->arguments();
2324 int arg_count = args->length(); 2324 int arg_count = args->length();
2325 { PreservePositionScope scope(masm()->positions_recorder()); 2325
2326 for (int i = 0; i < arg_count; i++) { 2326 CallFunctionFlags flags;
2327 VisitForStackValue(args->at(i)); 2327 // Get the target function.
2328 if (callee->IsVariableProxy()) {
2329 { StackValueContext context(this);
2330 EmitVariableLoad(callee->AsVariableProxy());
2331 PrepareForBailout(callee, NO_REGISTERS);
2328 } 2332 }
2329 __ Mov(x2, Operand(name)); 2333 // Push undefined as receiver. This is patched in the method prologue if it
2334 // is a classic mode method.
2335 __ Push(isolate()->factory()->undefined_value());
2336 flags = NO_CALL_FUNCTION_FLAGS;
2337 } else {
2338 // Load the function from the receiver.
2339 ASSERT(callee->IsProperty());
2340 __ Peek(x0, 0);
2341 EmitNamedPropertyLoad(callee->AsProperty());
2342 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2343 // Push the target function under the receiver.
2344 __ Pop(x10);
2345 __ Push(x0, x10);
2346 flags = CALL_AS_METHOD;
2330 } 2347 }
2331 // Record source position for debugger.
2332 SetSourcePosition(expr->position());
2333 // Call the IC initialization code.
2334 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count);
2335 TypeFeedbackId ast_id = mode == CONTEXTUAL
2336 ? TypeFeedbackId::None()
2337 : expr->CallFeedbackId();
2338 CallIC(ic, mode, ast_id);
2339 RecordJSReturnSite(expr);
2340 // Restore context register.
2341 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2342 context()->Plug(x0);
2343 }
2344 2348
2345 2349 // Load the arguments.
2346 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2347 Expression* key) {
2348 // Load the key.
2349 VisitForAccumulatorValue(key);
2350 // Load the key.
2351
2352 // Swap the name of the function and the receiver on the stack to follow
2353 // the calling convention for call ICs.
2354 __ Pop(x1);
2355 __ Push(x0, x1);
2356
2357 // Code common for calls using the IC.
2358 ZoneList<Expression*>* args = expr->arguments();
2359 int arg_count = args->length();
2360 { PreservePositionScope scope(masm()->positions_recorder()); 2350 { PreservePositionScope scope(masm()->positions_recorder());
2361 for (int i = 0; i < arg_count; i++) { 2351 for (int i = 0; i < arg_count; i++) {
2362 VisitForStackValue(args->at(i)); 2352 VisitForStackValue(args->at(i));
2363 } 2353 }
2364 } 2354 }
2355
2365 // Record source position for debugger. 2356 // Record source position for debugger.
2366 SetSourcePosition(expr->position()); 2357 SetSourcePosition(expr->position());
2367 // Call the IC initialization code. 2358 CallFunctionStub stub(arg_count, flags);
2368 Handle<Code> ic = 2359 __ Peek(x1, (arg_count + 1) * kPointerSize);
2369 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); 2360 __ CallStub(&stub);
2370 __ Peek(x2, (arg_count + 1) * kXRegSizeInBytes); // Key. 2361
2371 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); 2362 RecordJSReturnSite(expr);
2363
2364 // Restore context register.
2365 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2366
2367 context()->DropAndPlug(1, x0);
2368 }
2369
2370
2371 // Code common for calls using the IC.
2372 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2373 Expression* key) {
2374 // Load the key.
2375 VisitForAccumulatorValue(key);
2376
2377 Expression* callee = expr->expression();
2378 ZoneList<Expression*>* args = expr->arguments();
2379 int arg_count = args->length();
2380
2381 // Load the function from the receiver.
2382 ASSERT(callee->IsProperty());
2383 __ Peek(x1, 0);
2384 EmitKeyedPropertyLoad(callee->AsProperty());
2385 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2386
2387 // Push the target function under the receiver.
2388 __ Pop(x10);
2389 __ Push(x0, x10);
2390
2391 { PreservePositionScope scope(masm()->positions_recorder());
2392 for (int i = 0; i < arg_count; i++) {
2393 VisitForStackValue(args->at(i));
2394 }
2395 }
2396
2397 // Record source position for debugger.
2398 SetSourcePosition(expr->position());
2399 CallFunctionStub stub(arg_count, CALL_AS_METHOD);
2400 __ Peek(x1, (arg_count + 1) * kPointerSize);
2401 __ CallStub(&stub);
2402
2372 RecordJSReturnSite(expr); 2403 RecordJSReturnSite(expr);
2373 // Restore context register. 2404 // Restore context register.
2374 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2405 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2375 context()->DropAndPlug(1, x0); // Drop the key still on the stack. 2406
2407 context()->DropAndPlug(1, x0);
2376 } 2408 }
2377 2409
2378 2410
2379 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2411 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2380 // Code common for calls using the call stub. 2412 // Code common for calls using the call stub.
2381 ZoneList<Expression*>* args = expr->arguments(); 2413 ZoneList<Expression*>* args = expr->arguments();
2382 int arg_count = args->length(); 2414 int arg_count = args->length();
2383 { PreservePositionScope scope(masm()->positions_recorder()); 2415 { PreservePositionScope scope(masm()->positions_recorder());
2384 for (int i = 0; i < arg_count; i++) { 2416 for (int i = 0; i < arg_count; i++) {
2385 VisitForStackValue(args->at(i)); 2417 VisitForStackValue(args->at(i));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2483 // Call the evaluated function. 2515 // Call the evaluated function.
2484 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); 2516 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
2485 __ Peek(x1, (arg_count + 1) * kXRegSizeInBytes); 2517 __ Peek(x1, (arg_count + 1) * kXRegSizeInBytes);
2486 __ CallStub(&stub); 2518 __ CallStub(&stub);
2487 RecordJSReturnSite(expr); 2519 RecordJSReturnSite(expr);
2488 // Restore context register. 2520 // Restore context register.
2489 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2521 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2490 context()->DropAndPlug(1, x0); 2522 context()->DropAndPlug(1, x0);
2491 2523
2492 } else if (call_type == Call::GLOBAL_CALL) { 2524 } else if (call_type == Call::GLOBAL_CALL) {
2493 // Push global object as receiver for the call IC. 2525 EmitCallWithIC(expr);
2494 __ Ldr(x10, GlobalObjectMemOperand());
2495 __ Push(x10);
2496 VariableProxy* proxy = callee->AsVariableProxy();
2497 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL);
2498 2526
2499 } else if (call_type == Call::LOOKUP_SLOT_CALL) { 2527 } else if (call_type == Call::LOOKUP_SLOT_CALL) {
2500 // Call to a lookup slot (dynamically introduced variable). 2528 // Call to a lookup slot (dynamically introduced variable).
2501 VariableProxy* proxy = callee->AsVariableProxy(); 2529 VariableProxy* proxy = callee->AsVariableProxy();
2502 Label slow, done; 2530 Label slow, done;
2503 2531
2504 { PreservePositionScope scope(masm()->positions_recorder()); 2532 { PreservePositionScope scope(masm()->positions_recorder());
2505 // Generate code for loading from variables potentially shadowed 2533 // Generate code for loading from variables potentially shadowed
2506 // by eval-introduced variables. 2534 // by eval-introduced variables.
2507 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2535 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
(...skipping 26 matching lines...) Expand all
2534 2562
2535 // The receiver is either the global receiver or an object found 2563 // The receiver is either the global receiver or an object found
2536 // by LoadContextSlot. 2564 // by LoadContextSlot.
2537 EmitCallWithStub(expr); 2565 EmitCallWithStub(expr);
2538 } else if (call_type == Call::PROPERTY_CALL) { 2566 } else if (call_type == Call::PROPERTY_CALL) {
2539 Property* property = callee->AsProperty(); 2567 Property* property = callee->AsProperty();
2540 { PreservePositionScope scope(masm()->positions_recorder()); 2568 { PreservePositionScope scope(masm()->positions_recorder());
2541 VisitForStackValue(property->obj()); 2569 VisitForStackValue(property->obj());
2542 } 2570 }
2543 if (property->key()->IsPropertyName()) { 2571 if (property->key()->IsPropertyName()) {
2544 EmitCallWithIC(expr, 2572 EmitCallWithIC(expr);
2545 property->key()->AsLiteral()->value(),
2546 NOT_CONTEXTUAL);
2547 } else { 2573 } else {
2548 EmitKeyedCallWithIC(expr, property->key()); 2574 EmitKeyedCallWithIC(expr, property->key());
2549 } 2575 }
2550 2576
2551 } else { 2577 } else {
2552 ASSERT(call_type == Call::OTHER_CALL); 2578 ASSERT(call_type == Call::OTHER_CALL);
2553 // Call to an arbitrary expression not handled specially above. 2579 // Call to an arbitrary expression not handled specially above.
2554 { PreservePositionScope scope(masm()->positions_recorder()); 2580 { PreservePositionScope scope(masm()->positions_recorder());
2555 VisitForStackValue(callee); 2581 VisitForStackValue(callee);
2556 } 2582 }
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after
3553 3579
3554 // Call runtime to perform the lookup. 3580 // Call runtime to perform the lookup.
3555 __ Push(cache, key); 3581 __ Push(cache, key);
3556 __ CallRuntime(Runtime::kGetFromCache, 2); 3582 __ CallRuntime(Runtime::kGetFromCache, 2);
3557 3583
3558 __ Bind(&done); 3584 __ Bind(&done);
3559 context()->Plug(x0); 3585 context()->Plug(x0);
3560 } 3586 }
3561 3587
3562 3588
3563 void FullCodeGenerator::EmitIsRegExpEquivalent(CallRuntime* expr) {
3564 ASM_UNIMPLEMENTED("EmitIsRegExpEquivalent has not been tested");
3565
3566 ZoneList<Expression*>* args = expr->arguments();
3567 ASSERT_EQ(2, args->length());
3568
3569 Register right = x2;
3570 Register left = x1;
3571
3572 VisitForStackValue(args->at(0));
3573 VisitForAccumulatorValue(args->at(1));
3574 __ Pop(left);
3575 __ Mov(right, x0);
3576
3577 // Speculatively set result to true.
3578 Register result = x0;
3579 __ LoadRoot(result, Heap::kTrueValueRootIndex);
3580
3581 Label fail, ok;
3582 __ Cmp(left, right);
3583 __ B(eq, &ok);
3584
3585 // Fail if either is a non-HeapObject.
3586 __ JumpIfEitherSmi(left, right, &fail);
3587
3588 Register left_map = x10;
3589 __ Ldr(left_map, FieldMemOperand(left, HeapObject::kMapOffset));
3590 __ Ldrb(x11, FieldMemOperand(left_map, Map::kInstanceTypeOffset));
3591 __ Cmp(x11, JS_REGEXP_TYPE);
3592 __ B(ne, &fail);
3593
3594 Register right_map = x11;
3595 __ Ldr(right_map, FieldMemOperand(right, HeapObject::kMapOffset));
3596 __ Cmp(left_map, right_map);
3597 __ B(ne, &fail);
3598
3599 __ Ldr(x10, FieldMemOperand(left, JSRegExp::kDataOffset));
3600 __ Ldr(x11, FieldMemOperand(right, JSRegExp::kDataOffset));
3601 __ Cmp(x10, x11);
3602 __ B(eq, &ok);
3603
3604 __ Bind(&fail);
3605 __ LoadRoot(result, Heap::kFalseValueRootIndex);
3606
3607 __ Bind(&ok);
3608 context()->Plug(result);
3609 }
3610
3611
3612 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3589 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3613 ZoneList<Expression*>* args = expr->arguments(); 3590 ZoneList<Expression*>* args = expr->arguments();
3614 VisitForAccumulatorValue(args->at(0)); 3591 VisitForAccumulatorValue(args->at(0));
3615 3592
3616 Label materialize_true, materialize_false; 3593 Label materialize_true, materialize_false;
3617 Label* if_true = NULL; 3594 Label* if_true = NULL;
3618 Label* if_false = NULL; 3595 Label* if_false = NULL;
3619 Label* fall_through = NULL; 3596 Label* fall_through = NULL;
3620 context()->PrepareTest(&materialize_true, &materialize_false, 3597 context()->PrepareTest(&materialize_true, &materialize_false,
3621 &if_true, &if_false, &fall_through); 3598 &if_true, &if_false, &fall_through);
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
3862 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3839 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3863 Handle<String> name = expr->name(); 3840 Handle<String> name = expr->name();
3864 if (name->length() > 0 && name->Get(0) == '_') { 3841 if (name->length() > 0 && name->Get(0) == '_') {
3865 Comment cmnt(masm_, "[ InlineRuntimeCall"); 3842 Comment cmnt(masm_, "[ InlineRuntimeCall");
3866 EmitInlineRuntimeCall(expr); 3843 EmitInlineRuntimeCall(expr);
3867 return; 3844 return;
3868 } 3845 }
3869 3846
3870 Comment cmnt(masm_, "[ CallRunTime"); 3847 Comment cmnt(masm_, "[ CallRunTime");
3871 ZoneList<Expression*>* args = expr->arguments(); 3848 ZoneList<Expression*>* args = expr->arguments();
3849 int arg_count = args->length();
3872 3850
3873 if (expr->is_jsruntime()) { 3851 if (expr->is_jsruntime()) {
3874 // Prepare for calling JS runtime function. 3852 // Push the builtins object as the receiver.
3875 __ Ldr(x10, GlobalObjectMemOperand()); 3853 __ Ldr(x10, GlobalObjectMemOperand());
3876 __ Ldr(x11, FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); 3854 __ Ldr(x0, FieldMemOperand(x10, GlobalObject::kBuiltinsOffset));
3877 __ Push(x11); 3855 __ Push(x0);
3878 }
3879 3856
3880 int arg_count = args->length(); 3857 // Load the function from the receiver.
3881 for (int i = 0; i < arg_count; i++) { 3858 __ Mov(x2, Operand(name));
3882 VisitForStackValue(args->at(i)); 3859 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
3883 }
3884 3860
3885 if (expr->is_jsruntime()) { 3861 // Push the target function under the receiver.
3886 // Call the JS runtime function. 3862 __ Pop(x10);
3887 __ Mov(x2, Operand(expr->name())); 3863 __ Push(x0, x10);
3888 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); 3864
3889 CallIC(ic, NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 3865 int arg_count = args->length();
3866 for (int i = 0; i < arg_count; i++) {
3867 VisitForStackValue(args->at(i));
3868 }
3869
3870 // Record source position of the IC call.
3871 SetSourcePosition(expr->position());
3872 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
3873 __ Peek(x1, (arg_count + 1) * kPointerSize);
3874 __ CallStub(&stub);
3875
3890 // Restore context register. 3876 // Restore context register.
3891 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3877 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3878
3879 context()->DropAndPlug(1, x0);
3892 } else { 3880 } else {
3881 // Push the arguments ("left-to-right").
3882 for (int i = 0; i < arg_count; i++) {
3883 VisitForStackValue(args->at(i));
3884 }
3885
3893 // Call the C runtime function. 3886 // Call the C runtime function.
3894 __ CallRuntime(expr->function(), arg_count); 3887 __ CallRuntime(expr->function(), arg_count);
3888 context()->Plug(x0);
3895 } 3889 }
3896
3897 context()->Plug(x0);
3898 } 3890 }
3899 3891
3900 3892
3901 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3893 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3902 switch (expr->op()) { 3894 switch (expr->op()) {
3903 case Token::DELETE: { 3895 case Token::DELETE: {
3904 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3896 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3905 Property* property = expr->expression()->AsProperty(); 3897 Property* property = expr->expression()->AsProperty();
3906 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3898 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3907 3899
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
4258 Split(eq, if_true, if_false, fall_through); 4250 Split(eq, if_true, if_false, fall_through);
4259 } else if (check->Equals(isolate()->heap()->string_string())) { 4251 } else if (check->Equals(isolate()->heap()->string_string())) {
4260 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof string_string"); 4252 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof string_string");
4261 __ JumpIfSmi(x0, if_false); 4253 __ JumpIfSmi(x0, if_false);
4262 // Check for undetectable objects => false. 4254 // Check for undetectable objects => false.
4263 __ JumpIfObjectType(x0, x0, x1, FIRST_NONSTRING_TYPE, if_false, ge); 4255 __ JumpIfObjectType(x0, x0, x1, FIRST_NONSTRING_TYPE, if_false, ge);
4264 __ Ldrb(x1, FieldMemOperand(x0, Map::kBitFieldOffset)); 4256 __ Ldrb(x1, FieldMemOperand(x0, Map::kBitFieldOffset));
4265 __ TestAndSplit(x1, 1 << Map::kIsUndetectable, if_true, if_false, 4257 __ TestAndSplit(x1, 1 << Map::kIsUndetectable, if_true, if_false,
4266 fall_through); 4258 fall_through);
4267 } else if (check->Equals(isolate()->heap()->symbol_string())) { 4259 } else if (check->Equals(isolate()->heap()->symbol_string())) {
4260 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof symbol_string");
4268 __ JumpIfSmi(x0, if_false); 4261 __ JumpIfSmi(x0, if_false);
4269 __ CompareObjectType(x0, x0, x1, SYMBOL_TYPE); 4262 __ CompareObjectType(x0, x0, x1, SYMBOL_TYPE);
4270 Split(eq, if_true, if_false, fall_through); 4263 Split(eq, if_true, if_false, fall_through);
4271 } else if (check->Equals(isolate()->heap()->boolean_string())) { 4264 } else if (check->Equals(isolate()->heap()->boolean_string())) {
4272 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof boolean_string"); 4265 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof boolean_string");
4273 __ JumpIfRoot(x0, Heap::kTrueValueRootIndex, if_true); 4266 __ JumpIfRoot(x0, Heap::kTrueValueRootIndex, if_true);
4274 __ CompareRoot(x0, Heap::kFalseValueRootIndex); 4267 __ CompareRoot(x0, Heap::kFalseValueRootIndex);
4275 Split(eq, if_true, if_false, fall_through); 4268 Split(eq, if_true, if_false, fall_through);
4276 } else if (FLAG_harmony_typeof && 4269 } else if (FLAG_harmony_typeof &&
4277 check->Equals(isolate()->heap()->null_string())) { 4270 check->Equals(isolate()->heap()->null_string())) {
4271 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof null_string");
4278 __ CompareRoot(x0, Heap::kNullValueRootIndex); 4272 __ CompareRoot(x0, Heap::kNullValueRootIndex);
4279 Split(eq, if_true, if_false, fall_through); 4273 Split(eq, if_true, if_false, fall_through);
4280 } else if (check->Equals(isolate()->heap()->undefined_string())) { 4274 } else if (check->Equals(isolate()->heap()->undefined_string())) {
4281 ASM_LOCATION( 4275 ASM_LOCATION(
4282 "FullCodeGenerator::EmitLiteralCompareTypeof undefined_string"); 4276 "FullCodeGenerator::EmitLiteralCompareTypeof undefined_string");
4283 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, if_true); 4277 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, if_true);
4284 __ JumpIfSmi(x0, if_false); 4278 __ JumpIfSmi(x0, if_false);
4285 // Check for undetectable objects => true. 4279 // Check for undetectable objects => true.
4286 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset)); 4280 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset));
4287 __ Ldrb(x1, FieldMemOperand(x0, Map::kBitFieldOffset)); 4281 __ Ldrb(x1, FieldMemOperand(x0, Map::kBitFieldOffset));
(...skipping 19 matching lines...) Expand all
4307 if_false, lt); 4301 if_false, lt);
4308 __ CompareInstanceType(map, x11, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4302 __ CompareInstanceType(map, x11, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
4309 __ B(gt, if_false); 4303 __ B(gt, if_false);
4310 // Check for undetectable objects => false. 4304 // Check for undetectable objects => false.
4311 __ Ldrb(x10, FieldMemOperand(map, Map::kBitFieldOffset)); 4305 __ Ldrb(x10, FieldMemOperand(map, Map::kBitFieldOffset));
4312 4306
4313 __ TestAndSplit(x10, 1 << Map::kIsUndetectable, if_true, if_false, 4307 __ TestAndSplit(x10, 1 << Map::kIsUndetectable, if_true, if_false,
4314 fall_through); 4308 fall_through);
4315 4309
4316 } else { 4310 } else {
4311 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof other");
4317 if (if_false != fall_through) __ B(if_false); 4312 if (if_false != fall_through) __ B(if_false);
4318 } 4313 }
4319 context()->Plug(if_true, if_false); 4314 context()->Plug(if_true, if_false);
4320 } 4315 }
4321 4316
4322 4317
4323 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 4318 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
4324 Comment cmnt(masm_, "[ CompareOperation"); 4319 Comment cmnt(masm_, "[ CompareOperation");
4325 SetSourcePosition(expr->position()); 4320 SetSourcePosition(expr->position());
4326 4321
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
4501 4496
4502 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 4497 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
4503 Label l_next, l_call, l_loop; 4498 Label l_next, l_call, l_loop;
4504 // Initial send value is undefined. 4499 // Initial send value is undefined.
4505 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 4500 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
4506 __ B(&l_next); 4501 __ B(&l_next);
4507 4502
4508 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 4503 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
4509 __ Bind(&l_catch); 4504 __ Bind(&l_catch);
4510 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 4505 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
4511 __ LoadRoot(x2, Heap::kthrow_stringRootIndex); // "throw" 4506 __ LoadRoot(x2, Heap::kthrow_stringRootIndex); // "throw"
4512 __ Peek(x3, 1 * kPointerSize); // iter 4507 __ Peek(x3, 1 * kPointerSize); // iter
4513 __ Push(x3); // iter 4508 __ Push(x2, x3, x0); // "throw", iter, except
4514 __ Push(x0); // exception
4515 __ B(&l_call); 4509 __ B(&l_call);
4516 4510
4517 // try { received = %yield result } 4511 // try { received = %yield result }
4518 // Shuffle the received result above a try handler and yield it without 4512 // Shuffle the received result above a try handler and yield it without
4519 // re-boxing. 4513 // re-boxing.
4520 __ Bind(&l_try); 4514 __ Bind(&l_try);
4521 __ Pop(x0); // result 4515 __ Pop(x0); // result
4522 __ PushTryHandler(StackHandler::CATCH, expr->index()); 4516 __ PushTryHandler(StackHandler::CATCH, expr->index());
4523 const int handler_size = StackHandlerConstants::kSize; 4517 const int handler_size = StackHandlerConstants::kSize;
4524 __ Push(x0); // result 4518 __ Push(x0); // result
(...skipping 18 matching lines...) Expand all
4543 kLRHasBeenSaved, kDontSaveFPRegs); 4537 kLRHasBeenSaved, kDontSaveFPRegs);
4544 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 4538 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
4545 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4539 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4546 __ Pop(x0); // result 4540 __ Pop(x0); // result
4547 EmitReturnSequence(); 4541 EmitReturnSequence();
4548 __ Bind(&l_resume); // received in x0 4542 __ Bind(&l_resume); // received in x0
4549 __ PopTryHandler(); 4543 __ PopTryHandler();
4550 4544
4551 // receiver = iter; f = 'next'; arg = received; 4545 // receiver = iter; f = 'next'; arg = received;
4552 __ Bind(&l_next); 4546 __ Bind(&l_next);
4553 __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next" 4547 __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next"
4554 __ Peek(x3, 1 * kPointerSize); // iter 4548 __ Peek(x3, 1 * kPointerSize); // iter
4555 __ Push(x3); // iter 4549 __ Push(x2, x3, x0); // "next", iter, received
4556 __ Push(x0); // received
4557 4550
4558 // result = receiver[f](arg); 4551 // result = receiver[f](arg);
4559 __ Bind(&l_call); 4552 __ Bind(&l_call);
4560 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); 4553 __ Peek(x1, 1 * kPointerSize);
4561 CallIC(ic); 4554 __ Peek(x0, 2 * kPointerSize);
4555 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
4556 CallIC(ic, NOT_CONTEXTUAL, TypeFeedbackId::None());
4557 __ Mov(x1, x0);
4558 __ Poke(x1, 2 * kPointerSize);
4559 CallFunctionStub stub(1, CALL_AS_METHOD);
4560 __ CallStub(&stub);
4561
4562 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4562 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4563 __ Drop(1); // The function is still on the stack; drop it.
4563 4564
4564 // if (!result.done) goto l_try; 4565 // if (!result.done) goto l_try;
4565 __ Bind(&l_loop); 4566 __ Bind(&l_loop);
4566 __ Push(x0); // save result 4567 __ Push(x0); // save result
4567 __ LoadRoot(x2, Heap::kdone_stringRootIndex); // "done" 4568 __ LoadRoot(x2, Heap::kdone_stringRootIndex); // "done"
4568 CallLoadIC(NOT_CONTEXTUAL); // result.done in x0 4569 CallLoadIC(NOT_CONTEXTUAL); // result.done in x0
4569 // The ToBooleanStub argument (result.done) is in x0. 4570 // The ToBooleanStub argument (result.done) is in x0.
4570 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 4571 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
4571 CallIC(bool_ic); 4572 CallIC(bool_ic);
4572 __ Cbz(x0, &l_try); 4573 __ Cbz(x0, &l_try);
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
5009 return previous_; 5010 return previous_;
5010 } 5011 }
5011 5012
5012 5013
5013 #undef __ 5014 #undef __
5014 5015
5015 5016
5016 } } // namespace v8::internal 5017 } } // namespace v8::internal
5017 5018
5018 #endif // V8_TARGET_ARCH_A64 5019 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/code-stubs-a64.cc ('k') | src/a64/ic-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698