Revision f230a1cf deps/v8/src/mips/stub-cache-mips.cc

View differences:

deps/v8/src/mips/stub-cache-mips.cc
374 374
                                            Register receiver,
375 375
                                            Register scratch1,
376 376
                                            Register scratch2,
377
                                            Label* miss,
378
                                            bool support_wrappers) {
377
                                            Label* miss) {
379 378
  Label check_wrapper;
380 379

  
381 380
  // Check if the object is a string leaving the instance type in the
382 381
  // scratch1 register.
383
  GenerateStringCheck(masm, receiver, scratch1, scratch2, miss,
384
                      support_wrappers ? &check_wrapper : miss);
382
  GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper);
385 383

  
386 384
  // Load length directly from the string.
387 385
  __ Ret(USE_DELAY_SLOT);
388 386
  __ lw(v0, FieldMemOperand(receiver, String::kLengthOffset));
389 387

  
390
  if (support_wrappers) {
391
    // Check if the object is a JSValue wrapper.
392
    __ bind(&check_wrapper);
393
    __ Branch(miss, ne, scratch1, Operand(JS_VALUE_TYPE));
388
  // Check if the object is a JSValue wrapper.
389
  __ bind(&check_wrapper);
390
  __ Branch(miss, ne, scratch1, Operand(JS_VALUE_TYPE));
394 391

  
395
    // Unwrap the value and check if the wrapped value is a string.
396
    __ lw(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
397
    GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
398
    __ Ret(USE_DELAY_SLOT);
399
    __ lw(v0, FieldMemOperand(scratch1, String::kLengthOffset));
400
  }
392
  // Unwrap the value and check if the wrapped value is a string.
393
  __ lw(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
394
  GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
395
  __ Ret(USE_DELAY_SLOT);
396
  __ lw(v0, FieldMemOperand(scratch1, String::kLengthOffset));
401 397
}
402 398

  
403 399

  
......
429 425
}
430 426

  
431 427

  
432
void BaseStoreStubCompiler::GenerateNegativeHolderLookup(
428
void StoreStubCompiler::GenerateNegativeHolderLookup(
433 429
    MacroAssembler* masm,
434 430
    Handle<JSObject> holder,
435 431
    Register holder_reg,
......
448 444
// Generate StoreTransition code, value is passed in a0 register.
449 445
// After executing generated code, the receiver_reg and name_reg
450 446
// may be clobbered.
451
void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
452
                                                    Handle<JSObject> object,
453
                                                    LookupResult* lookup,
454
                                                    Handle<Map> transition,
455
                                                    Handle<Name> name,
456
                                                    Register receiver_reg,
457
                                                    Register storage_reg,
458
                                                    Register value_reg,
459
                                                    Register scratch1,
460
                                                    Register scratch2,
461
                                                    Register scratch3,
462
                                                    Label* miss_label,
463
                                                    Label* slow) {
447
void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
448
                                                Handle<JSObject> object,
449
                                                LookupResult* lookup,
450
                                                Handle<Map> transition,
451
                                                Handle<Name> name,
452
                                                Register receiver_reg,
453
                                                Register storage_reg,
454
                                                Register value_reg,
455
                                                Register scratch1,
456
                                                Register scratch2,
457
                                                Register scratch3,
458
                                                Label* miss_label,
459
                                                Label* slow) {
464 460
  // a0 : value.
465 461
  Label exit;
466 462

  
......
612 608
// When leaving generated code after success, the receiver_reg and name_reg
613 609
// may be clobbered.  Upon branch to miss_label, the receiver and name
614 610
// registers have their original values.
615
void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
616
                                               Handle<JSObject> object,
617
                                               LookupResult* lookup,
618
                                               Register receiver_reg,
619
                                               Register name_reg,
620
                                               Register value_reg,
621
                                               Register scratch1,
622
                                               Register scratch2,
623
                                               Label* miss_label) {
611
void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
612
                                           Handle<JSObject> object,
613
                                           LookupResult* lookup,
614
                                           Register receiver_reg,
615
                                           Register name_reg,
616
                                           Register value_reg,
617
                                           Register scratch1,
618
                                           Register scratch2,
619
                                           Label* miss_label) {
624 620
  // a0 : value
625 621
  Label exit;
626 622

  
......
733 729
}
734 730

  
735 731

  
736
void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
737
                                                Label* label,
738
                                                Handle<Name> name) {
732
void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
733
                                            Label* label,
734
                                            Handle<Name> name) {
739 735
  if (!label->is_unused()) {
740 736
    __ bind(label);
741 737
    __ li(this->name(), Operand(name));
......
833 829

  
834 830
static void GenerateFastApiDirectCall(MacroAssembler* masm,
835 831
                                      const CallOptimization& optimization,
836
                                      int argc) {
832
                                      int argc,
833
                                      bool restore_context) {
837 834
  // ----------- S t a t e -------------
838
  //  -- sp[0]              : holder (set by CheckPrototypes)
839
  //  -- sp[4]              : callee JS function
840
  //  -- sp[8]              : call data
841
  //  -- sp[12]             : isolate
842
  //  -- sp[16]             : ReturnValue default value
843
  //  -- sp[20]             : ReturnValue
844
  //  -- sp[24]             : last JS argument
835
  //  -- sp[0] - sp[24]     : FunctionCallbackInfo, incl.
836
  //                        :  holder (set by CheckPrototypes)
837
  //  -- sp[28]             : last JS argument
845 838
  //  -- ...
846
  //  -- sp[(argc + 5) * 4] : first JS argument
847
  //  -- sp[(argc + 6) * 4] : receiver
839
  //  -- sp[(argc + 6) * 4] : first JS argument
840
  //  -- sp[(argc + 7) * 4] : receiver
848 841
  // -----------------------------------
842
  typedef FunctionCallbackArguments FCA;
843
  // Save calling context.
844
  __ sw(cp, MemOperand(sp, FCA::kContextSaveIndex * kPointerSize));
849 845
  // Get the function and setup the context.
850 846
  Handle<JSFunction> function = optimization.constant_function();
851 847
  __ LoadHeapObject(t1, function);
852 848
  __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset));
849
  __ sw(t1, MemOperand(sp, FCA::kCalleeIndex * kPointerSize));
853 850

  
854
  // Pass the additional arguments.
851
  // Construct the FunctionCallbackInfo.
855 852
  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
856 853
  Handle<Object> call_data(api_call_info->data(), masm->isolate());
857 854
  if (masm->isolate()->heap()->InNewSpace(*call_data)) {
......
860 857
  } else {
861 858
    __ li(t2, call_data);
862 859
  }
863

  
860
  // Store call data.
861
  __ sw(t2, MemOperand(sp, FCA::kDataIndex * kPointerSize));
862
  // Store isolate.
864 863
  __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate())));
865
  // Store JS function, call data, isolate ReturnValue default and ReturnValue.
866
  __ sw(t1, MemOperand(sp, 1 * kPointerSize));
867
  __ sw(t2, MemOperand(sp, 2 * kPointerSize));
868
  __ sw(t3, MemOperand(sp, 3 * kPointerSize));
864
  __ sw(t3, MemOperand(sp, FCA::kIsolateIndex * kPointerSize));
865
  // Store ReturnValue default and ReturnValue.
869 866
  __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
870
  __ sw(t1, MemOperand(sp, 4 * kPointerSize));
871
  __ sw(t1, MemOperand(sp, 5 * kPointerSize));
867
  __ sw(t1, MemOperand(sp, FCA::kReturnValueOffset * kPointerSize));
868
  __ sw(t1, MemOperand(sp, FCA::kReturnValueDefaultValueIndex * kPointerSize));
872 869

  
873 870
  // Prepare arguments.
874
  __ Addu(a2, sp, Operand(5 * kPointerSize));
871
  __ Move(a2, sp);
875 872

  
876 873
  // Allocate the v8::Arguments structure in the arguments' space since
877 874
  // it's not controlled by GC.
......
880 877
  FrameScope frame_scope(masm, StackFrame::MANUAL);
881 878
  __ EnterExitFrame(false, kApiStackSpace);
882 879

  
883
  // a0 = v8::Arguments&
880
  // a0 = FunctionCallbackInfo&
884 881
  // Arguments is built at sp + 1 (sp is a reserved spot for ra).
885 882
  __ Addu(a0, sp, kPointerSize);
886

  
887
  // v8::Arguments::implicit_args_
883
  // FunctionCallbackInfo::implicit_args_
888 884
  __ sw(a2, MemOperand(a0, 0 * kPointerSize));
889
  // v8::Arguments::values_
890
  __ Addu(t0, a2, Operand(argc * kPointerSize));
885
  // FunctionCallbackInfo::values_
886
  __ Addu(t0, a2, Operand((kFastApiCallArguments - 1 + argc) * kPointerSize));
891 887
  __ sw(t0, MemOperand(a0, 1 * kPointerSize));
892
  // v8::Arguments::length_ = argc
888
  // FunctionCallbackInfo::length_ = argc
893 889
  __ li(t0, Operand(argc));
894 890
  __ sw(t0, MemOperand(a0, 2 * kPointerSize));
895
  // v8::Arguments::is_construct_call = 0
891
  // FunctionCallbackInfo::is_construct_call = 0
896 892
  __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
897 893

  
898 894
  const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
......
910 906
      masm->isolate());
911 907

  
912 908
  AllowExternalCallThatCantCauseGC scope(masm);
909
  MemOperand context_restore_operand(
910
      fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
911
  MemOperand return_value_operand(
912
      fp, (2 + FCA::kReturnValueOffset) * kPointerSize);
913

  
913 914
  __ CallApiFunctionAndReturn(ref,
914 915
                              function_address,
915 916
                              thunk_ref,
916 917
                              a1,
917 918
                              kStackUnwindSpace,
918
                              kFastApiCallArguments + 1);
919
                              return_value_operand,
920
                              restore_context ?
921
                                  &context_restore_operand : NULL);
919 922
}
920 923

  
921 924

  
......
929 932
  ASSERT(optimization.is_simple_api_call());
930 933
  ASSERT(!receiver.is(scratch));
931 934

  
935
  typedef FunctionCallbackArguments FCA;
932 936
  const int stack_space = kFastApiCallArguments + argc + 1;
933 937
  // Assign stack space for the call arguments.
934 938
  __ Subu(sp, sp, Operand(stack_space * kPointerSize));
935 939
  // Write holder to stack frame.
936
  __ sw(receiver, MemOperand(sp, 0));
940
  __ sw(receiver, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
937 941
  // Write receiver to stack frame.
938 942
  int index = stack_space - 1;
939 943
  __ sw(receiver, MemOperand(sp, index * kPointerSize));
......
944 948
    __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
945 949
  }
946 950

  
947
  GenerateFastApiDirectCall(masm, optimization, argc);
951
  GenerateFastApiDirectCall(masm, optimization, argc, true);
948 952
}
949 953

  
950 954

  
......
1058 1062

  
1059 1063
    // Invoke function.
1060 1064
    if (can_do_fast_api_call) {
1061
      GenerateFastApiDirectCall(masm, optimization, arguments_.immediate());
1065
      GenerateFastApiDirectCall(
1066
          masm, optimization, arguments_.immediate(), false);
1062 1067
    } else {
1063 1068
      CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
1064 1069
          ? CALL_AS_FUNCTION
......
1199 1204
  Register reg = object_reg;
1200 1205
  int depth = 0;
1201 1206

  
1207
  typedef FunctionCallbackArguments FCA;
1202 1208
  if (save_at_depth == depth) {
1203
    __ sw(reg, MemOperand(sp));
1209
    __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
1204 1210
  }
1205 1211

  
1206 1212
  // Check the maps in the prototype chain.
......
1258 1264
    }
1259 1265

  
1260 1266
    if (save_at_depth == depth) {
1261
      __ sw(reg, MemOperand(sp));
1267
      __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
1262 1268
    }
1263 1269

  
1264 1270
    // Go to the next object in the prototype chain.
......
1290 1296
}
1291 1297

  
1292 1298

  
1293
void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1294
                                                 Label* success,
1295
                                                 Label* miss) {
1299
void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1300
                                             Label* success,
1301
                                             Label* miss) {
1296 1302
  if (!miss->is_unused()) {
1297 1303
    __ Branch(success);
1298 1304
    __ bind(miss);
......
1301 1307
}
1302 1308

  
1303 1309

  
1304
void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1305
                                                  Label* success,
1306
                                                  Label* miss) {
1310
void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1311
                                              Label* success,
1312
                                              Label* miss) {
1307 1313
  if (!miss->is_unused()) {
1308 1314
    __ b(success);
1309 1315
    GenerateRestoreName(masm(), miss, name);
......
1312 1318
}
1313 1319

  
1314 1320

  
1315
Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1321
Register LoadStubCompiler::CallbackHandlerFrontend(
1316 1322
    Handle<JSObject> object,
1317 1323
    Register object_reg,
1318 1324
    Handle<JSObject> holder,
......
1358 1364
}
1359 1365

  
1360 1366

  
1361
void BaseLoadStubCompiler::NonexistentHandlerFrontend(
1367
void LoadStubCompiler::NonexistentHandlerFrontend(
1362 1368
    Handle<JSObject> object,
1363 1369
    Handle<JSObject> last,
1364 1370
    Handle<Name> name,
......
1378 1384
}
1379 1385

  
1380 1386

  
1381
void BaseLoadStubCompiler::GenerateLoadField(Register reg,
1382
                                             Handle<JSObject> holder,
1383
                                             PropertyIndex field,
1384
                                             Representation representation) {
1387
void LoadStubCompiler::GenerateLoadField(Register reg,
1388
                                         Handle<JSObject> holder,
1389
                                         PropertyIndex field,
1390
                                         Representation representation) {
1385 1391
  if (!reg.is(receiver())) __ mov(receiver(), reg);
1386 1392
  if (kind() == Code::LOAD_IC) {
1387 1393
    LoadFieldStub stub(field.is_inobject(holder),
......
1397 1403
}
1398 1404

  
1399 1405

  
1400
void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1406
void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1401 1407
  // Return the constant value.
1402 1408
  __ LoadObject(v0, value);
1403 1409
  __ Ret();
1404 1410
}
1405 1411

  
1406 1412

  
1407
void BaseLoadStubCompiler::GenerateLoadCallback(
1413
void LoadStubCompiler::GenerateLoadCallback(
1408 1414
    const CallOptimization& call_optimization) {
1409 1415
  GenerateFastApiCall(
1410 1416
      masm(), call_optimization, receiver(), scratch3(), 0, NULL);
1411 1417
}
1412 1418

  
1413 1419

  
1414
void BaseLoadStubCompiler::GenerateLoadCallback(
1420
void LoadStubCompiler::GenerateLoadCallback(
1415 1421
    Register reg,
1416 1422
    Handle<ExecutableAccessorInfo> callback) {
1417 1423
  // Build AccessorInfo::args_ list on the stack and push property name below
1418 1424
  // the exit frame to make GC aware of them and store pointers to them.
1419
  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0);
1420
  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1);
1421
  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2);
1422
  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3);
1423
  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4);
1424
  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5);
1425
  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
1426
  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
1427
  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
1428
  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
1429
  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
1430
  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
1431
  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
1425 1432
  ASSERT(!scratch2().is(reg));
1426 1433
  ASSERT(!scratch3().is(reg));
1427 1434
  ASSERT(!scratch4().is(reg));
1428 1435
  __ push(receiver());
1429
  __ mov(scratch2(), sp);  // scratch2 = AccessorInfo::args_
1430 1436
  if (heap()->InNewSpace(callback->data())) {
1431 1437
    __ li(scratch3(), callback);
1432 1438
    __ lw(scratch3(), FieldMemOperand(scratch3(),
......
1444 1450
  __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize));
1445 1451
  __ sw(reg, MemOperand(sp, 1 * kPointerSize));
1446 1452
  __ sw(name(), MemOperand(sp, 0 * kPointerSize));
1453
  __ Addu(scratch2(), sp, 1 * kPointerSize);
1447 1454

  
1448 1455
  __ mov(a2, scratch2());  // Saved in case scratch2 == a1.
1449 1456
  __ mov(a0, sp);  // (first argument - a0) = Handle<Name>
......
1452 1459
  FrameScope frame_scope(masm(), StackFrame::MANUAL);
1453 1460
  __ EnterExitFrame(false, kApiStackSpace);
1454 1461

  
1455
  // Create AccessorInfo instance on the stack above the exit frame with
1462
  // Create PropertyAccessorInfo instance on the stack above the exit frame with
1456 1463
  // scratch2 (internal::Object** args_) as the data.
1457 1464
  __ sw(a2, MemOperand(sp, kPointerSize));
1458 1465
  // (second argument - a1) = AccessorInfo&
1459 1466
  __ Addu(a1, sp, kPointerSize);
1460 1467

  
1461
  const int kStackUnwindSpace = kFastApiCallArguments + 1;
1468
  const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
1462 1469
  Address getter_address = v8::ToCData<Address>(callback->getter());
1463 1470
  ApiFunction fun(getter_address);
1464 1471
  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
......
1475 1482
                              thunk_ref,
1476 1483
                              a2,
1477 1484
                              kStackUnwindSpace,
1478
                              6);
1485
                              MemOperand(fp, 6 * kPointerSize),
1486
                              NULL);
1479 1487
}
1480 1488

  
1481 1489

  
1482
void BaseLoadStubCompiler::GenerateLoadInterceptor(
1490
void LoadStubCompiler::GenerateLoadInterceptor(
1483 1491
    Register holder_reg,
1484 1492
    Handle<JSObject> object,
1485 1493
    Handle<JSObject> interceptor_holder,
......
2558 2566
  CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name,
2559 2567
                  depth, &miss);
2560 2568

  
2561
  GenerateFastApiDirectCall(masm(), optimization, argc);
2569
  GenerateFastApiDirectCall(masm(), optimization, argc, false);
2562 2570

  
2563 2571
  __ bind(&miss);
2564 2572
  FreeSpaceForFastApiCall(masm());
......
3011 3019

  
3012 3020

  
3013 3021
void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
3022
                                             Register receiver,
3014 3023
                                             Handle<JSFunction> getter) {
3015 3024
  // ----------- S t a t e -------------
3016 3025
  //  -- a0    : receiver
......
3022 3031

  
3023 3032
    if (!getter.is_null()) {
3024 3033
      // Call the JavaScript getter with the receiver on the stack.
3025
      __ push(a0);
3034
      __ push(receiver);
3026 3035
      ParameterCount actual(0);
3027 3036
      ParameterCount expected(getter);
3028 3037
      __ InvokeFunction(getter, expected, actual,

Also available in: Unified diff