| Index: src/arm/lithium-codegen-arm.cc
 | 
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
 | 
| index 8dd35b6b8394251c79842b7a56e4097d82b5cd5b..5ade3d64a20f4c82ea624f27378dfe206164bcf6 100644
 | 
| --- a/src/arm/lithium-codegen-arm.cc
 | 
| +++ b/src/arm/lithium-codegen-arm.cc
 | 
| @@ -3098,6 +3098,56 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
 | 
| +  class DeferredStringCharFromCode: public LDeferredCode {
 | 
| +   public:
 | 
| +    DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
 | 
| +        : LDeferredCode(codegen), instr_(instr) { }
 | 
| +    virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
 | 
| +   private:
 | 
| +    LStringCharFromCode* instr_;
 | 
| +  };
 | 
| +
 | 
| +  DeferredStringCharFromCode* deferred =
 | 
| +      new DeferredStringCharFromCode(this, instr);
 | 
| +
 | 
| +  ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
 | 
| +  Register char_code = ToRegister(instr->char_code());
 | 
| +  Register result = ToRegister(instr->result());
 | 
| +  ASSERT(!char_code.is(result));
 | 
| +
 | 
| +  __ cmp(char_code, Operand(String::kMaxAsciiCharCode));
 | 
| +  __ b(hi, deferred->entry());
 | 
| +  __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
 | 
| +  __ add(result, result, Operand(char_code, LSL, kPointerSizeLog2));
 | 
| +  __ ldr(result, FieldMemOperand(result, FixedArray::kHeaderSize));
 | 
| +  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
 | 
| +  __ cmp(result, ip);
 | 
| +  __ b(eq, deferred->entry());
 | 
| +  __ bind(deferred->exit());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
 | 
| +  Register char_code = ToRegister(instr->char_code());
 | 
| +  Register result = ToRegister(instr->result());
 | 
| +
 | 
| +  // TODO(3095996): Get rid of this. For now, we need to make the
 | 
| +  // result register contain a valid pointer because it is already
 | 
| +  // contained in the register pointer map.
 | 
| +  __ mov(result, Operand(0));
 | 
| +
 | 
| +  __ PushSafepointRegisters();
 | 
| +  __ SmiTag(char_code);
 | 
| +  __ push(char_code);
 | 
| +  __ CallRuntimeSaveDoubles(Runtime::kCharFromCode);
 | 
| +  RecordSafepointWithRegisters(
 | 
| +      instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex);
 | 
| +  __ StoreToSafepointRegisterSlot(r0, result);
 | 
| +  __ PopSafepointRegisters();
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void LCodeGen::DoStringLength(LStringLength* instr) {
 | 
|    Register string = ToRegister(instr->InputAt(0));
 | 
|    Register result = ToRegister(instr->result());
 | 
| 
 |